Prometheus Pull与Push模式应用场景深度解析

2026/06/09 共 7898 字,约 23 分钟

一、引言

在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 PodPull + 服务发现
批处理任务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

原因

  • 存储过多指标
  • 高基数标签导致内存膨胀

解决方案

# 限制推送指标数量
# 在推送端进行过滤和聚合

十、总结

核心要点

  1. Pull模式是Prometheus的默认采集方式,适用于长期运行的服务、Kubernetes环境和需要服务发现的场景。

  2. Push模式仅通过Pushgateway实现,适用于短生命周期的批处理任务和服务级别的批量作业。

  3. 官方明确指出:Pushgateway仅推荐用于捕获服务级批处理作业的执行结果,不适用于机器级别指标。

  4. 机器级别指标应使用Node Exporter的textfile collector,而非Pushgateway。

  5. 生产环境建议采用Pull模式为主、Push模式为辅的混合架构,根据具体场景选择合适的采集方式。

选型建议

场景推荐方案
Web服务、微服务Pull模式 + 服务发现
批处理、定时任务Pushgateway
CI/CD流水线Pushgateway
机器级别指标Node Exporter textfile
网络隔离环境PushProx或Push模式

本文对应的面试题:Prometheus获取数据什么时候会用pull,什么时候会用push?

文档信息

Search

    Table of Contents