一、引言
在Prometheus监控体系中,数据采集模式的选择是架构设计的关键决策。虽然Prometheus默认采用Pull模式,但在实际生产环境中,单一模式往往无法满足所有场景需求。本文将深入探讨Prometheus在不同场景下选择Pull或Push模式的决策依据,帮助您构建高效、可靠的监控采集架构。
二、SCQA分析框架
情境(Situation)
- 监控系统需要覆盖长期运行服务和短暂任务
- 云原生环境下服务动态扩缩容成为常态
- 网络隔离环境增加监控难度
冲突(Complication)
- Pull模式无法捕获短生命周期任务
- Push模式存在单点故障和指标过期风险
- 错误使用Pushgateway会导致运维问题
问题(Question)
- 什么场景适合使用Pull模式?
- 什么场景适合使用Push模式?
- Pushgateway的正确使用方式是什么?
- 如何避免Pushgateway的常见陷阱?
- 生产环境如何设计混合采集架构?
答案(Answer)
- Pull模式适合长期运行服务和需要服务发现的场景
- Push模式仅适合短生命周期批处理任务
- 遵循官方指导,仅用Pushgateway处理服务级批处理作业
- 采用Pull为主、Push为辅的混合架构
三、Pull模式的适用场景
3.1 长期运行服务
典型场景:
- Web服务、API网关、微服务
- 数据库、缓存服务
- 消息队列、中间件
技术原理:
Prometheus Server定期向目标发起HTTP GET请求
从/metrics端点获取指标数据
配置示例:
scrape_configs:
- job_name: 'api-gateway'
scrape_interval: 15s
scrape_timeout: 10s
metrics_path: /metrics
static_configs:
- targets:
- 'api-gateway-1:8080'
- 'api-gateway-2:8080'
- 'api-gateway-3:8080'
优势:
- 自动健康检测(up指标)
- 服务发现集成
- 集中配置管理
3.2 Kubernetes环境
技术原理:
通过Kubernetes API自动发现Pod、Node、Service
动态更新监控目标列表
配置示例:
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
regex: 'true'
action: keep
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
regex: (.+)
target_label: __metrics_path__
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: ${1}:${2}
target_label: __address__
优势:
- 自动适应Pod扩缩容
- 无需手动维护目标列表
- 支持基于标签的灵活筛选
3.3 需要服务发现的场景
技术原理:
通过Consul、DNS、EC2等服务发现机制
自动发现新增的监控目标
配置示例:
scrape_configs:
- job_name: 'consul-services'
consul_sd_configs:
- server: 'consul:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_service]
regex: 'backend.*'
action: keep
优势:
- 动态环境自适应
- 减少人工操作
- 提高监控覆盖率
四、Push模式(Pushgateway)的适用场景
4.1 短生命周期批处理任务
典型场景:
- ETL数据处理任务
- 定时备份任务
- 数据迁移任务
- 一次性脚本执行
技术原理:
批处理任务完成前将指标推送到Pushgateway
Prometheus从Pushgateway拉取指标
推送示例(Shell):
#!/bin/bash
# ETL任务执行脚本
start_time=$(date +%s)
# 执行ETL任务
python etl_job.py
end_time=$(date +%s)
duration=$((end_time - start_time))
# 推送执行结果到Pushgateway
echo "etl_job_duration_seconds $duration" | curl --data-binary @- \
http://pushgateway:9091/metrics/job/etl_job/instance/etl-01
推送示例(Python):
import time
import requests
def run_etl_job():
start_time = time.time()
# 执行ETL逻辑
process_data()
duration = time.time() - start_time
# 推送指标
metrics = f"etl_job_duration_seconds {duration}"
response = requests.post(
"http://pushgateway:9091/metrics/job/etl_job",
data=metrics
)
response.raise_for_status()
if __name__ == "__main__":
run_etl_job()
4.2 服务级别的批量作业
典型场景:
- 每日账单生成
- 月度报表计算
- 全局数据统计
- 服务级别健康检查
关键特征:
不与特定机器绑定
服务层面的统计指标
跨多个实例的聚合结果
4.3 网络隔离环境
典型场景:
- 跨防火墙监控
- NAT环境监控
- 多区域分布式监控
- 边缘计算环境
替代方案:PushProx
# PushProx配置
scrape_configs:
- job_name: 'pushprox-client'
proxy_url: 'http://pushprox-proxy:8080'
static_configs:
- targets: ['node-exporter:9100']
五、Pushgateway使用原则与风险
5.1 官方推荐原则
唯一有效场景:
捕获服务级批处理作业的执行结果
官方警告:
We only recommend using the Pushgateway in certain limited cases.
5.2 使用风险
风险一:单点故障
Pushgateway成为单一故障点
所有推送任务依赖Pushgateway可用性
风险二:失去健康检测
Pushgateway不生成up指标
无法自动检测任务健康状态
风险三:指标过期问题
Pushgateway不会自动删除指标
任务结束后指标持续存在
需要手动清理
5.3 最佳实践配置
scrape_configs:
- job_name: 'pushgateway'
honor_labels: true
scrape_interval: 10s
scrape_timeout: 5s
static_configs:
- targets: ['pushgateway:9091']
relabel_configs:
- source_labels: [__name__]
regex: 'batch_job.*|etl_job.*|cron_job.*'
action: keep
关键配置说明:
honor_labels: true:保留原始标签,防止标签冲突- 合理的scrape_interval:平衡实时性和资源消耗
- relabel_configs:过滤非预期指标
六、场景决策矩阵
6.1 决策流程图
监控目标是否长期运行?
├── 是 → 使用Pull模式
│ └── 是否需要服务发现?
│ ├── 是 → 配置服务发现
│ └── 否 → 静态配置
└── 否 → 是否为服务级批处理任务?
├── 是 → 使用Pushgateway
│ └── 注意清理过期指标
└── 否 → 使用Node Exporter textfile collector
6.2 场景对比表
| 场景类型 | 推荐模式 | 配置复杂度 | 风险等级 | 维护成本 |
|---|---|---|---|---|
| 长期运行服务 | Pull | 低 | 低 | 低 |
| Kubernetes Pod | Pull + 服务发现 | 中 | 低 | 低 |
| 批处理任务 | Push(Pushgateway) | 中 | 中 | 中 |
| CI/CD流水线 | Push(Pushgateway) | 低 | 中 | 中 |
| 机器级别指标 | Pull(Node Exporter) | 低 | 低 | 低 |
| 网络隔离环境 | Push或PushProx | 高 | 中 | 高 |
6.3 选型决策树
监控目标类型
│
┌───────────────┼───────────────┐
▼ ▼ ▼
长期运行 短暂任务 网络隔离
(服务/进程) (批处理/定时) (跨防火墙)
│ │ │
▼ ▼ ▼
Pull模式 Pushgateway Push/PushProx
│ │ │
┌─────────┴─────────┐ │ │
▼ ▼ ▼ ▼
静态配置 服务发现 服务级任务 代理方案
七、避免使用Pushgateway的场景
7.1 机器级别的指标
反模式示例:
# ❌ 错误:使用Pushgateway推送机器级别指标
echo "disk_usage_percent 85" | curl --data-binary @- \
http://pushgateway:9091/metrics/job/node_metrics/instance/node1
推荐方案:
# ✅ 正确:使用Node Exporter textfile collector
echo "disk_usage_percent 85" > /var/lib/node_exporter/disk.prom
textfile collector配置:
# node-exporter启动参数
--collector.textfile.directory=/var/lib/node_exporter
7.2 高基数指标
问题分析:
Pushgateway内存存储
大量高基数指标会导致内存溢出
推荐方案:
使用Prometheus远程写入
或选择其他时序数据库存储
7.3 需要高可用的场景
问题分析:
Pushgateway默认单实例部署
存在单点故障风险
高可用方案:
# 多副本部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: pushgateway
spec:
replicas: 3
selector:
matchLabels:
app: pushgateway
template:
spec:
containers:
- name: pushgateway
image: prom/pushgateway:latest
ports:
- containerPort: 9091
args:
- --persistence.file=/data/metrics
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pushgateway-data
八、生产环境最佳实践
8.1 混合架构设计
┌─────────────────────────────────────────────────────────────────┐
│ Prometheus Server │
│ │ │
│ ┌─────────────────────┼─────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────────┐ ┌───────────┐ │
│ │ Pull模式 │ │ Pushgateway │ │ Remote │ │
│ │ (长期服务) │ │ (批处理任务) │ │ Write │ │
│ └─────┬─────┘ └───────┬───────┘ └─────┬─────┘ │
│ │ │ │ │
└─────────┼─────────────────────┼─────────────────────┼─────────┘
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Web服务 │ │ ETL任务 │ │ Thanos │
│ 数据库 │ │ 备份任务 │ │ (长期存储) │
│ Node │ │ CI/CD │ └───────────┘
│ Exporter │ │ 流水线 │
└───────────┘ └───────────┘
8.2 配置最佳实践
全局配置:
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: production
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- /etc/prometheus/rules/*.yml
Pull模式配置:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
scrape_interval: 10s
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__meta_kubernetes_node_name]
target_label: node
- job_name: 'kubernetes-services'
scrape_interval: 15s
kubernetes_sd_configs:
- role: service
Pushgateway配置:
scrape_configs:
- job_name: 'pushgateway'
honor_labels: true
scrape_interval: 10s
scrape_timeout: 5s
static_configs:
- targets: ['pushgateway:9091']
relabel_configs:
- source_labels: [__name__]
regex: 'batch_job.*|cron_job.*|etl_job.*'
action: keep
8.3 指标生命周期管理
指标清理策略:
# 清理过期指标脚本
#!/bin/bash
# 删除30天前的指标
curl -X DELETE "http://pushgateway:9091/api/v1/admin/wipe"
# 或删除特定job
curl -X DELETE "http://pushgateway:9091/metrics/job/old_job"
自动化清理:
apiVersion: batch/v1
kind: CronJob
metadata:
name: pushgateway-cleanup
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup
image: curlimages/curl
command:
- /bin/sh
- -c
- curl -X DELETE http://pushgateway:9091/api/v1/admin/wipe
restartPolicy: OnFailure
8.4 安全最佳实践
认证配置:
scrape_configs:
- job_name: 'pushgateway'
basic_auth:
username: admin
password: secret
static_configs:
- targets: ['pushgateway:9091']
TLS配置:
scrape_configs:
- job_name: 'pushgateway'
scheme: https
tls_config:
ca_file: /etc/prometheus/tls/ca.crt
cert_file: /etc/prometheus/tls/client.crt
key_file: /etc/prometheus/tls/client.key
static_configs:
- targets: ['pushgateway:9091']
九、常见问题与解决方案
问题一:Pushgateway数据积压
现象:
# Pushgateway内存持续增长
curl http://pushgateway:9091/metrics | grep pushgateway_build_info
原因:
- 指标未及时清理
- 任务重复推送相同指标
解决方案:
# 任务完成后主动清理
curl -X DELETE http://pushgateway:9091/metrics/job/my_job
# 或使用grouping标签管理
echo "metric_name 42" | curl --data-binary @- \
http://pushgateway:9091/metrics/job/my_job/instance/unique_id
问题二:指标标签冲突
现象:
# 查询时标签被覆盖
promql> batch_job_duration_seconds
# 返回的job标签不是预期值
原因:
honor_labels未启用- Prometheus覆盖了原始标签
解决方案:
scrape_configs:
- job_name: 'pushgateway'
honor_labels: true # 关键配置
static_configs:
- targets: ['pushgateway:9091']
问题三:单点故障
现象:
# Pushgateway宕机导致批处理指标丢失
kubectl get pods | grep pushgateway
# pushgateway-0 0/1 CrashLoopBackOff
解决方案:
# 多副本部署
spec:
replicas: 3
selector:
matchLabels:
app: pushgateway
问题四:内存占用过高
现象:
# Pushgateway内存使用率超过80%
kubectl top pods pushgateway-0
# NAME CPU(cores) MEMORY(bytes)
# pushgateway-0 100m 512Mi
原因:
- 存储过多指标
- 高基数标签导致内存膨胀
解决方案:
# 限制推送指标数量
# 在推送端进行过滤和聚合
十、总结
核心要点
Pull模式是Prometheus的默认采集方式,适用于长期运行的服务、Kubernetes环境和需要服务发现的场景。
Push模式仅通过Pushgateway实现,适用于短生命周期的批处理任务和服务级别的批量作业。
官方明确指出:Pushgateway仅推荐用于捕获服务级批处理作业的执行结果,不适用于机器级别指标。
机器级别指标应使用Node Exporter的textfile collector,而非Pushgateway。
生产环境建议采用Pull模式为主、Push模式为辅的混合架构,根据具体场景选择合适的采集方式。
选型建议
| 场景 | 推荐方案 |
|---|---|
| Web服务、微服务 | Pull模式 + 服务发现 |
| 批处理、定时任务 | Pushgateway |
| CI/CD流水线 | Pushgateway |
| 机器级别指标 | Node Exporter textfile |
| 网络隔离环境 | PushProx或Push模式 |
本文对应的面试题:Prometheus获取数据什么时候会用pull,什么时候会用push?
文档信息
- 本文作者:soveran zhong
- 本文链接:https://blog.clockwingsoar.cn/2026/06/09/prometheus-pull-push-scenarios/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)