Prometheus 监控体系使用指南

Prometheus 监控体系使用指南

本文以 Prometheus Server、Prometheus Agent、Prometheus Pushgateway 为主线,介绍三者的功能、使用场景、配置方式和对比分析。

文档结构调整为:

  • 主体章节:集中介绍 Prometheus Server、Prometheus Agent、Pushgateway 和三者对比分析。
  • 附录:补充 Grafana、PromQL、remote_write、VictoriaMetrics、组合架构、排查和示例。

说明:文中将 prometheus 作为官方组件名称使用。用户提到的 promethus 通常是 prometheus 的拼写误写。


目录


1. Prometheus 核心组件与对比分析

本章集中介绍 Prometheus 监控体系中最核心的三个组件:Prometheus Server、Prometheus Agent 和 Prometheus Pushgateway,并在最后给出对比分析和选型建议。


1.1 Prometheus Server

1.1.1 是什么

Prometheus Server 是 Prometheus 监控体系的核心组件。它通过 HTTP 定期从目标服务的 /metrics 接口拉取指标,将数据写入本地时序数据库 TSDB,并提供 PromQL 查询、规则计算和告警能力。

典型架构:

Application / Exporter
        |
        | scrape /metrics
        v
Prometheus Server
        |
        | query
        v
Grafana
        |
        | alert rules
        v
Alertmanager

Prometheus 的核心设计是 pull 模式:Prometheus 主动去目标服务抓取指标,而不是默认要求业务服务主动上报。


1.1.2 核心功能

1.1.2.1 指标抓取

Prometheus 按照配置周期性访问目标服务的 HTTP endpoint,例如:

http://app:8080/metrics
http://node-exporter:9100/metrics

目标服务需要暴露 Prometheus 文本格式指标,例如:

http_requests_total{method="GET",code="200"} 1027
process_cpu_seconds_total 12.34

1.1.2.2 服务发现

Prometheus 支持多种服务发现方式:

  • static_configs:静态目标列表。
  • file_sd_configs:从文件读取目标。
  • kubernetes_sd_configs:Kubernetes 服务发现。
  • consul_sd_configs:Consul 服务发现。
  • dns_sd_configs:DNS 服务发现。
  • http_sd_configs:HTTP 服务发现。
  • 云厂商服务发现,例如 EC2、GCE、Azure 等。

静态服务发现示例:

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app-1:8080
          - app-2:8080

Kubernetes 服务发现示例:

scrape_configs:
  - job_name: kubernetes-pods
    kubernetes_sd_configs:
      - role: pod

1.1.2.3 本地时序存储 TSDB

Prometheus Server 内置本地时序数据库 TSDB,默认将采集到的数据保存在本地磁盘。

常见启动参数:

--storage.tsdb.path=/prometheus
--storage.tsdb.retention.time=15d
--storage.tsdb.retention.size=100GB

含义:

参数 说明
--storage.tsdb.path 本地 TSDB 数据目录
--storage.tsdb.retention.time 按时间保留数据
--storage.tsdb.retention.size 按磁盘容量保留数据

1.1.2.4 PromQL 查询

Prometheus 提供 PromQL 查询语言,用于聚合、过滤、计算指标。

示例:

up

查看目标是否存活。

rate(http_requests_total[5m])

计算最近 5 分钟 HTTP 请求速率。

sum by (job) (rate(http_requests_total[5m]))

按 job 聚合请求速率。

histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

计算 P95 延迟。


1.1.2.5 Recording Rules

Recording rules 用于将复杂 PromQL 结果预先计算并保存成新指标,提升查询性能。

rules.yml 示例:

groups:
  - name: app-recording-rules
    rules:
      - record: job:http_requests:rate5m
        expr: sum by (job) (rate(http_requests_total[5m]))

Prometheus 配置中引用:

rule_files:
  - rules.yml

1.1.2.6 Alerting Rules

Prometheus 可以基于 PromQL 计算告警规则,并将告警发送给 Alertmanager。

alerts.yml 示例:

groups:
  - name: app-alerts
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} is down"

Prometheus 配置:

rule_files:
  - alerts.yml

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093

1.1.2.7 remote_write

Prometheus Server 支持通过 remote_write 将采集到的时间序列样本写入远端存储。该能力常用于中心化存储、多集群指标汇聚和长期保留场景。

详细功能、认证、队列、标签和 relabel 配置见 6. remote_write 功能与配置方式


1.1.3 使用场景

1.1.3.1 单集群或中小规模监控

如果只有一个 Kubernetes 集群或少量主机,可以直接使用 Prometheus Server:

Exporter / App -> Prometheus Server -> Grafana

适合:

  • 本地查询;
  • 本地告警;
  • 本地存储 7 到 30 天数据;
  • 运维复杂度较低的场景。

1.1.3.2 Kubernetes 监控

Prometheus 常用于 Kubernetes 集群监控,通常配合:

  • kube-state-metrics
  • node-exporter
  • cAdvisor / kubelet metrics
  • Prometheus Operator
  • ServiceMonitor / PodMonitor
  • Grafana Dashboard

典型架构:

Kubernetes workloads
Kubernetes nodes
Kubernetes control plane
        |
        v
Prometheus Server
        |
        v
Grafana / Alertmanager

1.1.3.3 应用性能监控

业务服务通过 SDK 暴露指标:

  • HTTP 请求量;
  • HTTP 错误率;
  • 请求延迟;
  • 队列长度;
  • 业务成功率;
  • JVM / Go runtime / Python runtime 指标。

1.1.3.4 基础设施监控

通过 exporter 采集系统和中间件指标:

目标 常用 exporter
Linux 主机 node-exporter
MySQL mysqld-exporter
Redis redis-exporter
PostgreSQL postgres-exporter
Nginx nginx-prometheus-exporter
Kafka kafka-exporter / JMX exporter
JVM 应用 jmx-exporter

1.1.4 基础配置方式

1.1.4.1 最小配置

prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets:
          - localhost:9090

启动:

prometheus --config.file=prometheus.yml

访问:

http://localhost:9090

1.1.4.2 采集 Node Exporter

prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: node
    static_configs:
      - targets:
          - node-exporter:9100

Node Exporter 暴露:

http://node-exporter:9100/metrics

1.1.4.3 Docker 运行
docker run -d \
  --name prometheus \
  -p 9090:9090 \
  -v ./prometheus.yml:/etc/prometheus/prometheus.yml \
  -v ./prometheus-data:/prometheus \
  prom/prometheus:latest \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/prometheus \
  --storage.tsdb.retention.time=15d

1.1.4.4 Kubernetes 使用方式

基础 Deployment 示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus:latest
          args:
            - --config.file=/etc/prometheus/prometheus.yml
            - --storage.tsdb.path=/prometheus
            - --storage.tsdb.retention.time=15d
          ports:
            - containerPort: 9090
          volumeMounts:
            - name: config
              mountPath: /etc/prometheus
            - name: data
              mountPath: /prometheus
      volumes:
        - name: config
          configMap:
            name: prometheus-config
        - name: data
          emptyDir: {}

生产环境通常建议使用 Prometheus Operator 或 kube-prometheus-stack。


1.1.5 Prometheus 配置结构

完整配置常见结构:

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    cluster: prod-a
    env: prod

rule_files:
  - rules/*.yml

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093

remote_write:
  - url: http://remote-storage/api/v1/write

关键配置说明:

配置项 说明
global.scrape_interval 默认抓取周期
global.evaluation_interval 规则计算周期
global.external_labels 写入远端或告警时附加的全局标签
rule_files 规则文件路径
scrape_configs 抓取配置
alerting Alertmanager 配置
remote_write 远端写入配置

1.1.6 适合与不适合

适合使用 Prometheus Server:

  • 需要本地 PromQL 查询;
  • 需要本地告警规则;
  • 需要 recording rules;
  • 需要本地保留一定历史数据;
  • 集群规模不大,单 Prometheus 可以承载;
  • 希望快速搭建完整监控系统。

不太适合:

  • 很多集群都部署完整 Prometheus,运维成本高;
  • 只需要采集转发,不需要本地查询;
  • 长期存储要求很高;
  • 超大规模指标,需要水平扩展的中心化存储。

1.2 Prometheus Agent

1.2.1 是什么

Prometheus Agent 是 Prometheus 的一种运行模式,也叫 Agent mode

它保留 Prometheus 的服务发现、指标抓取、relabel 和 remote_write 能力,但不作为完整查询和长期存储后端使用。

可以把它理解为:

Prometheus Agent = 轻量采集器 + remote_write 转发器

典型架构:

Application / Exporter
        |
        | scrape /metrics
        v
Prometheus Agent
        |
        | remote_write
        v
Mimir / Thanos Receive / Cortex / VictoriaMetrics
        |
        v
Grafana / Ruler / Alerting

1.2.2 核心功能

1.2.2.1 指标抓取

Agent 与 Prometheus Server 一样支持 scrape 配置:

scrape_configs:
  - job_name: app
    metrics_path: /metrics
    static_configs:
      - targets:
          - app:8080

1.2.2.2 服务发现

Agent 支持 Prometheus 的主流服务发现能力,例如:

scrape_configs:
  - job_name: kubernetes-pods
    kubernetes_sd_configs:
      - role: pod

这意味着你可以把原有 Prometheus Server 的 scrape 配置迁移到 Agent。


1.2.2.3 relabel 和 metric_relabel

Agent 支持抓取前 target relabel:

relabel_configs:
  - source_labels:
      - __meta_kubernetes_pod_annotation_prometheus_io_scrape
    action: keep
    regex: "true"

也支持抓取后的 metric relabel:

metric_relabel_configs:
  - source_labels:
      - __name__
    regex: "go_memstats_.*"
    action: drop

这对于降低 remote_write 成本非常重要。


1.2.2.4 remote_write

Agent 的核心输出方式是 remote_write。Prometheus Agent 本身不承担本地长期存储和查询职责,因此采集到的数据通常必须写入远端指标系统。

基础配置:

remote_write:
  - url: http://mimir-nginx/api/v1/push

带认证:

remote_write:
  - url: https://metrics.example.com/api/v1/write
    bearer_token_file: /etc/prometheus/token

带 Basic Auth:

remote_write:
  - url: https://metrics.example.com/api/v1/write
    basic_auth:
      username: prometheus-agent
      password_file: /etc/prometheus/remote-write-password

带 TLS:

remote_write:
  - url: https://metrics.example.com/api/v1/write
    tls_config:
      ca_file: /etc/prometheus/ca.crt
      cert_file: /etc/prometheus/client.crt
      key_file: /etc/prometheus/client.key

带队列配置:

remote_write:
  - url: http://remote-storage/api/v1/write
    queue_config:
      capacity: 10000
      min_shards: 1
      max_shards: 20
      max_samples_per_send: 2000
      batch_send_deadline: 5s
      min_backoff: 30ms
      max_backoff: 5s

Agent 场景下建议同时配置 external_labels

global:
  external_labels:
    cluster: prod-a
    region: cn-shanghai
    env: prod

remote_write:
  - url: http://remote-storage/api/v1/write

这样远端存储可以区分不同 Agent、不同集群、不同环境写入的同名指标。

Agent 也可以只把部分指标写入远端:

remote_write:
  - url: http://remote-storage/api/v1/write
    write_relabel_configs:
      - source_labels:
          - job
        regex: "debug-service|test-service"
        action: drop

如果要同时写入多个远端后端,可以配置多个 remote_write:

remote_write:
  - name: primary
    url: http://mimir/api/v1/push

  - name: backup
    url: http://victoriametrics/api/v1/write

Agent 的 remote_write 配置建议:

  • 为每个 Agent 配置清晰的 external_labels,尤其是 clusterenvregion
  • 使用 metric_relabel_configswrite_relabel_configs 过滤无用指标,降低远端写入成本。
  • 给 WAL 目录配置持久化存储,避免 Agent 重启时丢失未发送样本。
  • 监控 remote_write pending、failed、retried、dropped 等指标。
  • 不要把 remote_write 当成强一致消息队列;远端长时间不可用时仍可能丢数据。

1.2.2.5 本地 WAL 缓冲

Agent 并非完全无状态,它会使用本地 WAL 暂存待发送数据。

scrape -> WAL -> remote_write -> remote storage

当远端短暂不可用时,Agent 可以依靠 WAL 和 remote_write 重试机制缓冲一段时间。

注意:

  • WAL 不是长期存储;
  • 远端长期不可用时仍可能丢数据;
  • 生产环境建议给 Agent 的 WAL 目录挂载持久化卷。

1.2.3 与 Prometheus Server 的区别

能力 Prometheus Server Prometheus Agent
服务发现 支持 支持
指标抓取 支持 支持
relabel 支持 支持
metric_relabel 支持 支持
remote_write 支持 核心能力
本地 TSDB 长期存储 支持 不作为长期存储
PromQL 查询 支持 不适合作为查询后端
Graph UI 支持 不适合作为主要查询入口
recording rules 支持 不适合
alerting rules 支持 不适合
多集群采集端 可以 更适合
中心化监控架构 可以 更适合

1.2.4 使用场景

1.2.4.1 多集群中心化监控

多个集群分别部署 Agent,把数据写入统一后端:

Cluster A Prometheus Agent
Cluster B Prometheus Agent
Cluster C Prometheus Agent
        |
        v
Central Mimir / Thanos / VictoriaMetrics
        |
        v
Grafana

优点:

  • 每个集群采集端更轻;
  • 查询、告警、存储集中管理;
  • 多集群视图统一;
  • 避免每个集群维护完整 Prometheus。

1.2.4.2 边缘节点或分支机房采集

边缘节点本地只跑 Agent,中心机房部署远端存储:

Edge Apps -> Prometheus Agent -> Central Metrics Backend

适合:

  • 边缘计算;
  • 分支 IDC;
  • 多地域业务;
  • 网络链路有限但需要集中观测。

1.2.4.3 替代 Federation 的采集层

传统多 Prometheus 聚合可能使用 federation:

Prometheus A -> Federation Prometheus
Prometheus B -> Federation Prometheus

现代中心化架构更常用:

Prometheus Agent -> remote_write -> Central Backend

通常更适合大规模指标写入和统一查询。


1.2.4.4 降低采集端资源开销

如果采集端不需要查询和告警,Agent 比完整 Prometheus 更合适。

适合:

  • 采集点数量多;
  • 每个采集点资源有限;
  • 采集配置和服务发现仍希望沿用 Prometheus 语义;
  • 已经有远端存储平台。

1.2.5 基础配置方式

1.2.5.1 最小配置

prometheus-agent.yml

global:
  scrape_interval: 15s
  external_labels:
    cluster: demo-cluster
    env: prod

scrape_configs:
  - job_name: prometheus-agent
    static_configs:
      - targets:
          - localhost:9090

  - job_name: app
    static_configs:
      - targets:
          - app:8080

remote_write:
  - url: http://remote-storage:9090/api/v1/write

启动:

prometheus \
  --config.file=prometheus-agent.yml \
  --agent \
  --storage.agent.path=./agent-data

某些较老版本的 Prometheus Agent mode 曾使用 feature flag。实际使用时可通过 prometheus --help 确认当前版本参数。


1.2.5.2 Docker 运行
docker run -d \
  --name prometheus-agent \
  -p 9090:9090 \
  -v ./prometheus-agent.yml:/etc/prometheus/prometheus.yml \
  -v ./agent-data:/prometheus-agent \
  prom/prometheus:latest \
  --config.file=/etc/prometheus/prometheus.yml \
  --agent \
  --storage.agent.path=/prometheus-agent

1.2.5.3 Kubernetes Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-agent
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus-agent
  template:
    metadata:
      labels:
        app: prometheus-agent
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus:latest
          args:
            - --config.file=/etc/prometheus/prometheus.yml
            - --agent
            - --storage.agent.path=/prometheus-agent
          ports:
            - containerPort: 9090
          volumeMounts:
            - name: config
              mountPath: /etc/prometheus
            - name: data
              mountPath: /prometheus-agent
      volumes:
        - name: config
          configMap:
            name: prometheus-agent-config
        - name: data
          emptyDir: {}

ConfigMap 示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-agent-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      external_labels:
        cluster: demo-k8s
        env: prod

    scrape_configs:
      - job_name: prometheus-agent
        static_configs:
          - targets:
              - localhost:9090

    remote_write:
      - url: http://mimir-nginx.monitoring.svc.cluster.local/api/v1/push

1.2.5.4 Prometheus Operator 中的 PrometheusAgent

在 Prometheus Operator 生态中,可以使用 PrometheusAgent 资源,具体字段取决于 Operator 版本。

示例:

apiVersion: monitoring.coreos.com/v1alpha1
kind: PrometheusAgent
metadata:
  name: agent
  namespace: monitoring
spec:
  replicas: 1
  serviceMonitorSelector: {}
  podMonitorSelector: {}
  remoteWrite:
    - url: http://mimir-nginx.monitoring.svc.cluster.local/api/v1/push
  externalLabels:
    cluster: demo-k8s
    env: prod

这种方式适合 Kubernetes 生产环境,因为它可以复用 ServiceMonitor、PodMonitor 等 Operator 资源。


1.2.6 使用建议

1.2.6.1 必须配置 external_labels

多集群 remote_write 时建议配置:

global:
  external_labels:
    cluster: prod-a
    region: cn-shanghai
    env: prod

否则远端存储里多个集群的同名指标难以区分。


1.2.6.2 控制高基数指标

remote_write 成本通常与样本量和 label 基数有关。建议在 Agent 侧过滤无用指标和 label:

metric_relabel_configs:
  - regex: pod_uid|container_id|image_id
    action: labeldrop

丢弃不需要的指标:

metric_relabel_configs:
  - source_labels:
      - __name__
    regex: "debug_.*|test_.*"
    action: drop

1.2.6.3 监控 Agent 自身

Agent 也暴露自身指标,可以抓取:

scrape_configs:
  - job_name: prometheus-agent
    static_configs:
      - targets:
          - localhost:9090

重点关注:

prometheus_remote_storage_samples_pending
prometheus_remote_storage_samples_failed_total
prometheus_remote_storage_samples_retried_total
prometheus_remote_storage_succeeded_samples_total
scrape_samples_scraped
scrape_samples_post_metric_relabeling
scrape_duration_seconds

1.2.7 适合与不适合

适合使用 Prometheus Agent:

  • 已有中心化指标后端;
  • 多集群统一采集;
  • 边缘采集;
  • 不需要采集端本地查询;
  • 不需要采集端本地告警;
  • 希望降低采集端资源消耗。

不适合:

  • 没有 remote_write 后端;
  • 需要本地 PromQL 查询;
  • 需要本地告警规则;
  • 需要本地 recording rules;
  • 需要采集端长期保存历史数据;
  • 远端网络长期不稳定且不能接受数据丢失。

什么时候不要用 prometheus-agent

不建议使用 Agent mode 的情况:

  1. 你需要在本地直接 PromQL 查询;
  2. 你需要本地 Grafana 直接查这个 Prometheus;
  3. 你需要本地 alerting rules;
  4. 你需要本地 recording rules;
  5. 你没有 remote_write 后端;
  6. 你希望本地保留长期历史数据;
  7. 你的网络经常长时间断连,但又不能丢指标。

这些场景更适合完整 Prometheus Server。


1.3 Prometheus Pushgateway

1.3.1 是什么

Prometheus Pushgateway 是 Prometheus 生态中的一个中转组件,用于支持 短生命周期任务 的指标采集。

Prometheus 默认是 pull 模式:

Prometheus -> scrape -> Application / Exporter

但有些任务生命周期很短,例如:

  • 定时任务;
  • 批处理任务;
  • CronJob;
  • 一次性脚本;
  • 数据同步任务;
  • 离线计算任务。

这些任务可能在 Prometheus 下次 scrape 前已经结束,Prometheus 来不及抓取它们的 /metrics

Pushgateway 提供一种方式,让任务结束前主动推送指标:

Batch Job -> push metrics -> Pushgateway <- scrape <- Prometheus

注意:Prometheus 仍然是 pull Pushgateway,而不是直接接收业务推送。


1.3.2 核心功能

1.3.2.1 接收短任务推送的指标

任务通过 HTTP 将指标推送到 Pushgateway:

cat <<'EOF' | curl --data-binary @- http://pushgateway:9091/metrics/job/demo_batch
batch_job_last_success_unixtime 1710000000
batch_job_duration_seconds 12.3
EOF

Pushgateway 保存这些指标,等待 Prometheus 抓取。


1.3.2.2 按 grouping key 区分任务

Pushgateway 通过 URL 路径中的 label 分组保存指标。

例如:

curl --data-binary @metrics.txt \
  http://pushgateway:9091/metrics/job/order_sync/instance/host-a

其中 grouping key 是:

job="order_sync", instance="host-a"

也可以增加更多维度:

curl --data-binary @metrics.txt \
  http://pushgateway:9091/metrics/job/order_sync/env/prod/region/cn-shanghai

1.3.2.3 支持 push、pushadd、delete

Pushgateway 的 HTTP API 常见操作:

方法 作用
PUT 替换该 grouping key 下的所有指标
POST 添加或更新指标,不删除其他已有指标
DELETE 删除该 grouping key 下的指标

PUT 示例:

cat metrics.txt | curl --data-binary @- \
  -X PUT http://pushgateway:9091/metrics/job/demo

POST 示例:

cat metrics.txt | curl --data-binary @- \
  -X POST http://pushgateway:9091/metrics/job/demo

DELETE 示例:

curl -X DELETE http://pushgateway:9091/metrics/job/demo

1.3.2.4 Prometheus 抓取 Pushgateway

Prometheus 不直接接收 push,而是定期抓取 Pushgateway:

scrape_configs:
  - job_name: pushgateway
    xxx_labels: true
    static_configs:
      - targets:
          - pushgateway:9091

xxx_labels: true 很重要。

原因是 Pushgateway 中的指标通常已经带有任务自身的 jobinstance 等 label。如果不设置 xxx_labels: true,Prometheus 可能会覆盖这些 label。


1.3.3 使用场景

1.3.3.1 批处理任务

例如每天凌晨执行数据统计任务:

cron -> data_warehouse_sync -> push metrics -> Pushgateway -> Prometheus

可以推送:

data_sync_last_success_unixtime
data_sync_duration_seconds
data_sync_records_total
data_sync_failed_records_total

1.3.3.2 Kubernetes CronJob

Kubernetes CronJob 运行很短,Pod 结束后 /metrics 不再存在。

此时可以在任务结束前推送:

CronJob Pod -> Pushgateway -> Prometheus

适合监控:

  • 最近一次成功时间;
  • 最近一次运行耗时;
  • 最近一次处理数据量;
  • 是否失败;
  • 失败原因分类计数。

1.3.3.3 离线脚本或一次性任务

例如备份脚本:

backup_database.sh -> push backup status -> Pushgateway

指标示例:

backup_last_success_unixtime 1710000000
backup_duration_seconds 83.2
backup_size_bytes 1234567890

1.3.3.4 无法被 Prometheus 直接访问的短任务

例如某些临时执行环境中,任务可以访问 Pushgateway,但 Prometheus 无法直接访问任务自身。

不过如果是长期运行服务,应优先让 Prometheus 直接抓取服务,而不是使用 Pushgateway。


1.3.4 不适合的场景

Pushgateway 不适合替代普通服务监控。

不建议用于:

  • 长期运行的 Web 服务;
  • 长期运行的 worker;
  • node-exporter 指标;
  • Kubernetes Pod 常规指标;
  • 高频实时指标上报;
  • 每个请求、每个用户、每个订单级别的事件上报;
  • 服务级健康检查。

原因:

  1. Pushgateway 中指标不会随着任务消失自动消失;
  2. 容易产生陈旧指标;
  3. 不适合高基数动态 label;
  4. 违背 Prometheus 对长期服务的 pull 模型;
  5. 失败任务可能来不及 push,导致误判。

对于长期服务,应使用:

Service exposes /metrics <- Prometheus scrape

对于事件流或日志,应考虑日志系统、Tracing 或事件管道,不要用 Pushgateway 承担。


1.3.5 基础部署方式

1.3.5.1 Docker 运行
docker run -d \
  --name pushgateway \
  -p 9091:9091 \
  prom/pushgateway:latest

访问 Web UI:

http://localhost:9091

1.3.5.2 Kubernetes Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pushgateway
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pushgateway
  template:
    metadata:
      labels:
        app: pushgateway
    spec:
      containers:
        - name: pushgateway
          image: prom/pushgateway:latest
          ports:
            - containerPort: 9091

Service:

apiVersion: v1
kind: Service
metadata:
  name: pushgateway
  namespace: monitoring
spec:
  selector:
    app: pushgateway
  ports:
    - name: http
      port: 9091
      targetPort: 9091

Prometheus 抓取配置:

scrape_configs:
  - job_name: pushgateway
    xxx_labels: true
    static_configs:
      - targets:
          - pushgateway.monitoring.svc.cluster.local:9091

1.3.6 推送指标示例

1.3.6.1 Shell 脚本推送
#!/usr/bin/env bash
set -euo pipefail

start_time=$(date +%s)

if ./run_batch_job.sh; then
  status=1
else
  status=0
fi

end_time=$(date +%s)
duration=$((end_time - start_time))

cat <<EOF | curl --data-binary @- http://pushgateway:9091/metrics/job/batch_job/instance/$(hostname)
batch_job_success ${status}
batch_job_last_run_unixtime ${end_time}
batch_job_duration_seconds ${duration}
EOF

exit $((1 - status))

指标含义:

指标 说明
batch_job_success 最近一次是否成功,1 成功,0 失败
batch_job_last_run_unixtime 最近一次运行结束时间
batch_job_duration_seconds 最近一次运行耗时

1.3.6.2 Python 推送

安装:

pip install prometheus-client

代码示例:

import time
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway

registry = CollectorRegistry()

last_success = Gauge(
    "batch_job_last_success_unixtime",
    "Last successful run timestamp",
    registry=registry,
)

duration = Gauge(
    "batch_job_duration_seconds",
    "Batch job duration in seconds",
    registry=registry,
)

start = time.time()

try:
    # 执行业务逻辑
    time.sleep(2)
    last_success.set_to_current_time()
finally:
    duration.set(time.time() - start)
    push_to_gateway(
        "pushgateway:9091",
        job="demo_batch",
        registry=registry,
    )

1.3.6.3 Java 推送思路

Java 可使用 Prometheus Java client,通常流程是:

  1. 创建 registry;
  2. 定义 Gauge / Counter;
  3. 任务执行结束后设置指标;
  4. 调用 PushGateway 推送。

伪代码:

CollectorRegistry registry = new CollectorRegistry();
Gauge duration = Gauge.build()
    .name("batch_job_duration_seconds")
    .help("Batch job duration")
    .register(registry);

duration.set(12.3);

PushGateway pg = new PushGateway("pushgateway:9091");
pg.pushAdd(registry, "demo_batch");

1.3.7 Prometheus 告警示例

1.3.7.1 任务太久没有成功
groups:
  - name: batch-alerts
    rules:
      - alert: BatchJobNoRecentSuccess
        expr: time() - batch_job_last_success_unixtime > 3600
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Batch job has no recent success"

1.3.7.2 最近一次任务失败
groups:
  - name: batch-alerts
    rules:
      - alert: BatchJobFailed
        expr: batch_job_success == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Batch job failed"

1.3.7.3 任务耗时过长
groups:
  - name: batch-alerts
    rules:
      - alert: BatchJobTooSlow
        expr: batch_job_duration_seconds > 600
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Batch job is too slow"

1.3.8 Pushgateway 使用建议

1.3.8.1 使用 Gauge 表示最后状态

批任务监控通常推荐使用 Gauge:

batch_job_last_success_unixtime
batch_job_duration_seconds
batch_job_success

因为 Pushgateway 保存的是最后一次推送结果,而不是持续抓取的实时服务状态。


1.3.8.2 避免高基数 label

不要使用这些 label:

user_id
order_id
request_id
task_id
uuid
timestamp

否则会导致 Pushgateway 和 Prometheus 中产生大量时间序列。

推荐 label:

job
env
region
cluster
instance

1.3.8.3 任务生命周期结束后是否删除

如果任务是固定周期任务,通常保留最后一次指标即可,不需要每次删除。

如果任务是一次性临时任务,结束后可以删除:

curl -X DELETE http://pushgateway:9091/metrics/job/temp_job/instance/host-a

否则可能留下陈旧指标。


1.3.8.4 不要用 Pushgateway 作为通用指标入口

如果大量服务都 push 到 Pushgateway,会带来问题:

  • 难以判断服务是否真的存活;
  • 指标可能陈旧;
  • Pushgateway 成为集中写入瓶颈;
  • label 管理容易失控;
  • 不符合 Prometheus 的服务发现和 pull 模型。

长期服务应直接暴露 /metrics


1.4 三者对比

维度 Prometheus Server Prometheus Agent Pushgateway
核心职责 抓取、存储、查询、规则、告警 抓取并 remote_write 转发 接收短任务 push,等待 Prometheus 抓取
数据采集模式 Pull Pull + remote_write Job push 到 Pushgateway,Prometheus pull Pushgateway
是否本地长期存储 否,仅 WAL 缓冲 否,仅保存被 push 的最新指标
是否支持 PromQL 查询 不适合作为查询后端
是否支持告警规则 不适合 否,由 Prometheus 对其抓取结果告警
典型对象 长期服务、Exporter、基础设施 多集群/边缘采集端 短生命周期批任务
典型输出 本地 TSDB、查询 API、告警、remote_write remote_write /metrics 供 Prometheus 抓取
是否适合长期服务 是,作为采集器 不建议
是否适合 CronJob 可以但容易错过短任务 可以但仍可能错过短任务 适合
是否需要远端存储 不必须 必须或强烈需要 不需要,但需要 Prometheus 抓取

1.5 如何选择

1.5.1 使用 Prometheus Server

选择 Prometheus Server,如果你需要:

  • 本地查询;
  • 本地告警;
  • 本地 recording rules;
  • 本地保存历史数据;
  • 快速搭建完整监控;
  • 单集群或中小规模监控。

推荐架构:

App / Exporter -> Prometheus Server -> Grafana / Alertmanager

1.5.2 使用 Prometheus Agent

选择 Prometheus Agent,如果你需要:

  • 多集群统一采集;
  • 中心化指标平台;
  • 降低采集端资源开销;
  • 采集端不需要查询和告警;
  • 指标统一写入 Mimir / Thanos / VictoriaMetrics。

推荐架构:

Cluster Apps / Exporters -> Prometheus Agent -> Central Metrics Backend -> Grafana

1.5.3 使用 Pushgateway

选择 Pushgateway,如果你需要监控:

  • CronJob;
  • 批处理任务;
  • 一次性脚本;
  • 运行时间短于 Prometheus 抓取周期的任务;
  • 没有长期 /metrics endpoint 的任务。

推荐架构:

Batch Job -> Pushgateway <- Prometheus Server -> Grafana / Alertmanager

附录 A. Prometheus 与 Grafana 如何配合使用

A.1 两者职责

Prometheus 和 Grafana 是监控体系中最常见的组合,但它们的职责不同:

组件 主要职责
Prometheus 采集指标、存储指标、提供 PromQL 查询能力、执行告警规则
Grafana 连接数据源、执行查询、制作仪表盘、展示趋势图、配置可视化告警

典型链路:

Application / Exporter
        |
        | expose /metrics
        v
Prometheus
        |
        | PromQL query
        v
Grafana
        |
        v
Dashboard / Alerting

Prometheus 负责把指标采集进来并提供查询接口,Grafana 通过 Prometheus datasource 查询这些指标,然后把结果展示成图表。


A.2 基本使用流程

A.2.1 应用或 Exporter 暴露指标

长期运行服务通常暴露 /metrics

http://app:8080/metrics

指标内容示例:

http_requests_total{method="GET",code="200"} 1024
http_requests_total{method="GET",code="500"} 12
process_cpu_seconds_total 123.45

A.2.2 Prometheus 抓取指标

prometheus.yml 示例:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

  - job_name: node
    static_configs:
      - targets:
          - node-exporter:9100

Prometheus 会周期性访问:

http://app:8080/metrics
http://node-exporter:9100/metrics

A.2.3 Grafana 添加 Prometheus 数据源

在 Grafana 中进入:

Connections -> Data sources -> Add data source -> Prometheus

填写 Prometheus 地址:

http://prometheus:9090

常见地址写法:

部署方式 Grafana 中填写的 URL
本机运行 http://localhost:9090
Docker Compose 同网络 http://prometheus:9090
Kubernetes Service http://prometheus.monitoring.svc.cluster.local:9090
查询 Thanos / Mimir / VictoriaMetrics 对应查询组件的 HTTP 地址

保存后点击 Save & test,测试通过后即可在 Dashboard 中查询 Prometheus。


A.2.4 Grafana 创建 Dashboard Panel

创建一个 Panel,选择 Prometheus datasource,然后填写 PromQL:

up

或:

sum by (job) (rate(http_requests_total[5m]))

Grafana 可以将查询结果展示为:

  • Time series
  • Stat
  • Gauge
  • Table
  • Bar chart
  • Heatmap

A.3 Docker Compose 示例

目录结构:

monitoring/
  docker-compose.yml
  prometheus.yml

prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets:
          - prometheus:9090

docker-compose.yml

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - prometheus

volumes:
  prometheus-data:
  grafana-data:

启动:

docker compose up -d

访问:

Prometheus: http://localhost:9090
Grafana:    http://localhost:3000

Grafana 中添加 Prometheus 数据源时,URL 填:

http://prometheus:9090

附录 B. PromQL 是什么,怎么使用

PromQL 全称是 Prometheus Query Language,即 Prometheus 查询语言。

PromQL 用于查询、过滤、聚合和计算 Prometheus 中的时序指标。它常用于:

  • Grafana Dashboard 查询;
  • Prometheus Web UI 查询;
  • Prometheus alerting rules;
  • Prometheus recording rules;
  • 计算请求速率、错误率、延迟分位数、资源使用率等指标。

B.1 PromQL 基本概念

B.1.1 Metric 指标

指标名示例:

up

up 表示目标是否抓取成功:

1 = 抓取成功
0 = 抓取失败

B.1.2 Label 标签

Prometheus 指标通常带有标签:

http_requests_total{method="GET", code="200", instance="app:8080"}

标签用于区分不同维度,例如方法、状态码、实例、服务、命名空间等。

按标签过滤:

http_requests_total{method="GET"}

B.1.3 Time Series 时间序列

一条时间序列由以下内容唯一确定:

指标名 + 一组 label

例如下面是两条不同的时间序列:

http_requests_total{method="GET",code="200"}
http_requests_total{method="GET",code="500"}

B.2 PromQL 基础写法

B.2.1 查询当前值

up
process_resident_memory_bytes

B.2.2 Label 过滤

精确匹配:

up{job="app"}

不等于:

up{job!="app"}

正则匹配:

up{job=~"app|node"}

正则不匹配:

up{instance!~"test.*"}

B.2.3 范围查询

http_requests_total[5m]

表示最近 5 分钟的原始样本。

常见时间单位:

单位 含义
s
m 分钟
h 小时
d
w
y

B.3 常用 PromQL 函数

B.3.1 rate:计算平均速率

rate() 常用于 Counter 类型指标,例如请求总数、错误总数、发送字节总数。

rate(http_requests_total[5m])

按 job 聚合:

sum by (job) (rate(http_requests_total[5m]))

B.3.2 irate:计算瞬时速率

irate(http_requests_total[1m])

irate() 更敏感,适合观察短时间波动;告警规则通常更推荐使用 rate()


B.3.3 increase:计算时间窗口内增长量

increase(http_requests_total[1h])

表示最近 1 小时请求总增长量。


B.3.4 sum / avg / max / min 聚合

求和:

sum(rate(http_requests_total[5m]))

按 job 求和:

sum by (job) (rate(http_requests_total[5m]))

平均:

avg by (instance) (rate(node_cpu_seconds_total[5m]))

最大值:

max by (instance) (node_memory_MemAvailable_bytes)

最小值:

min by (instance) (node_memory_MemAvailable_bytes)

B.3.5 histogram_quantile:计算 P95 / P99

如果应用暴露 Histogram 指标,例如:

http_request_duration_seconds_bucket

计算 P95 延迟:

histogram_quantile(
  0.95,
  sum by (le) (
    rate(http_request_duration_seconds_bucket[5m])
  )
)

按接口计算 P95:

histogram_quantile(
  0.95,
  sum by (path, le) (
    rate(http_request_duration_seconds_bucket[5m])
  )
)

计算 P99:

histogram_quantile(
  0.99,
  sum by (path, le) (
    rate(http_request_duration_seconds_bucket[5m])
  )
)

B.4 常见 PromQL 示例

B.4.1 查看服务是否存活

up

某个 job:

up{job="app"}

B.4.2 HTTP QPS

sum(rate(http_requests_total[5m]))

按服务统计:

sum by (job) (rate(http_requests_total[5m]))

按接口统计:

sum by (path) (rate(http_requests_total[5m]))

B.4.3 HTTP 5xx 错误率

5xx 错误 QPS:

sum(rate(http_requests_total{code=~"5.."}[5m]))

5xx 错误率:

sum(rate(http_requests_total{code=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))

按服务统计:

sum by (job) (rate(http_requests_total{code=~"5.."}[5m]))
/
sum by (job) (rate(http_requests_total[5m]))

B.4.4 CPU 使用率

使用 node-exporter 时,CPU 指标通常是 node_cpu_seconds_total

100 - (
  avg by (instance) (
    rate(node_cpu_seconds_total{mode="idle"}[5m])
  ) * 100
)

B.4.5 内存使用率

100 *
(
  1 -
  node_memory_MemAvailable_bytes
  /
  node_memory_MemTotal_bytes
)

B.4.6 磁盘使用率

100 *
(
  1 -
  node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}
  /
  node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}
)

B.4.7 最近 5 分钟请求量

sum(increase(http_requests_total[5m]))

按接口统计:

sum by (path) (increase(http_requests_total[5m]))

B.5 PromQL 在 Grafana 中的使用

Grafana Panel 中可以直接填写 PromQL:

sum by (job) (rate(http_requests_total[5m]))

Grafana 常用内置变量:

变量 说明
$__interval Grafana 根据当前时间范围和图表宽度自动计算的间隔
$__rate_interval Grafana 推荐用于 rate() 的动态时间窗口
$__range 当前 Dashboard 选择的时间范围

推荐在 Grafana 中使用:

rate(http_requests_total[$__rate_interval])

而不是固定写死:

rate(http_requests_total[5m])

Grafana 变量示例:

up{job=~"$job"}
up{instance=~"$instance"}

B.6 PromQL 用于告警规则

实例宕机告警:

groups:
  - name: basic-alerts
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} is down"

HTTP 5xx 错误率过高:

groups:
  - name: app-alerts
    rules:
      - alert: HighHttp5xxRate
        expr: |
          sum(rate(http_requests_total{code=~"5.."}[5m]))
          /
          sum(rate(http_requests_total[5m]))
          > 0.05
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "HTTP 5xx error rate is higher than 5%"

B.7 PromQL 用于 Recording Rules

复杂或高频查询可以通过 recording rules 预计算。

groups:
  - name: app-recording-rules
    rules:
      - record: job:http_requests:rate5m
        expr: sum by (job) (rate(http_requests_total[5m]))

之后 Grafana 可以直接查询:

job:http_requests:rate5m

优点:

  • 降低 Grafana 查询压力;
  • 复用复杂表达式;
  • 告警规则更简洁。

B.8 PromQL 使用注意事项

B.8.1 Counter 类型指标使用 rate 或 increase

Counter 是只增不减的指标,例如:

http_requests_total

通常不要直接画原始 Counter,而是使用:

rate(http_requests_total[5m])

或:

increase(http_requests_total[1h])

B.8.2 Gauge 类型指标可以直接查询

Gauge 是可升可降的指标,例如:

node_memory_MemAvailable_bytes
queue_size
temperature_celsius

可以直接查询:

queue_size

B.8.3 两边相除时 label 维度要对齐

例如按 job 计算错误率时,分子和分母都要按 job 聚合:

sum by (job) (rate(http_requests_total{code=~"5.."}[5m]))
/
sum by (job) (rate(http_requests_total[5m]))

B.8.4 避免高基数 label

不要在指标 label 中使用:

user_id
order_id
request_id
trace_id
timestamp
uuid

这些 label 会导致时间序列数量快速膨胀,影响 Prometheus 存储和 Grafana 查询性能。


附录 C. remote_write 功能与配置方式

remote_write 是 Prometheus 将采集到的时间序列样本写入远端系统的能力。它通常用于把本地 Prometheus 或 Prometheus Agent 采集的数据发送到集中式指标后端。

常见远端后端包括:

  • Thanos Receive
  • Cortex
  • Grafana Mimir
  • VictoriaMetrics
  • 兼容 Prometheus remote_write 协议的云监控或自建平台

典型链路:

Application / Exporter
        |
        | scrape
        v
Prometheus / Prometheus Agent
        |
        | remote_write
        v
Remote Storage
        |
        v
Grafana / Ruler / Alerting

remote_write 的关键特点:

  1. 异步发送:Prometheus 抓取样本后,通过 remote write 队列异步发送到远端。
  2. WAL 驱动:Prometheus 会先把样本写入本地 WAL,再由 remote write 组件读取并发送。
  3. 支持重试:远端短暂失败时会重试,避免瞬时网络问题导致立即丢数据。
  4. 支持多后端:可以配置多个 remote_write 目标,同时写入多个系统。
  5. 适合中心化存储:本地 Prometheus 保留短期数据,远端后端负责长期存储和全局查询。
  6. 不是查询协议remote_write 只负责写入。查询通常通过远端系统自己的 Query API、PromQL API 或 Grafana datasource 完成。

C.1 基础配置

remote_write:
  - url: http://mimir-nginx/api/v1/push

C.2 认证配置

C.2.1 Basic Auth

remote_write:
  - url: https://metrics.example.com/api/v1/write
    basic_auth:
      username: prometheus
      password: your-password

C.2.2 使用 password_file

remote_write:
  - url: https://metrics.example.com/api/v1/write
    basic_auth:
      username: prometheus
      password_file: /etc/prometheus/remote-write-password

C.2.3 Bearer Token

remote_write:
  - url: https://metrics.example.com/api/v1/write
    bearer_token_file: /etc/prometheus/token

C.3 TLS 配置

remote_write:
  - url: https://metrics.example.com/api/v1/write
    tls_config:
      ca_file: /etc/prometheus/ca.crt
      cert_file: /etc/prometheus/client.crt
      key_file: /etc/prometheus/client.key
      server_name: metrics.example.com

C.4 external_labels 全局标签

global:
  external_labels:
    cluster: prod-a
    region: cn-shanghai
    env: prod

remote_write:
  - url: http://remote-storage/api/v1/write

external_labels 在多集群场景非常重要。否则多个集群里的同名指标,例如 up{job="kubelet"},写入远端后会难以区分来源。

C.5 多 remote_write 目标

remote_write:
  - name: primary
    url: http://mimir/api/v1/push

  - name: backup
    url: http://victoriametrics/api/v1/write

C.6 write_relabel_configs 写入前过滤

remote_write:
  - url: http://remote-storage/api/v1/write
    write_relabel_configs:
      - source_labels:
          - __name__
        regex: "go_memstats_.*"
        action: drop

write_relabel_configsmetric_relabel_configs 的区别:

配置 生效位置 影响本地 TSDB 影响 remote_write
metric_relabel_configs 指标抓取后、入库前
write_relabel_configs remote_write 发送前

如果只是不想把某些指标写入远端,但仍想保留在本地 Prometheus 中,应使用 write_relabel_configs

C.7 queue_config 队列配置

remote_write:
  - url: http://remote-storage/api/v1/write
    queue_config:
      capacity: 10000
      min_shards: 1
      max_shards: 20
      max_samples_per_send: 2000
      batch_send_deadline: 5s
      min_backoff: 30ms
      max_backoff: 5s

C.7.1 常见队列参数

参数 说明
capacity 每个 shard 的样本队列容量。容量太小容易在远端慢时积压失败
min_shards 最小发送分片数
max_shards 最大发送分片数。样本量大时可提高并发发送能力
max_samples_per_send 每次请求最多发送多少样本
batch_send_deadline 批量发送等待时间,到期即使未满也发送
min_backoff 失败重试的最小退避时间
max_backoff 失败重试的最大退避时间

C.8 完整配置示例

global:
  scrape_interval: 15s
  external_labels:
    cluster: prod-a
    env: prod

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

remote_write:
  - name: central-mimir
    url: https://mimir.example.com/api/v1/push
    bearer_token_file: /etc/prometheus/remote-write-token
    queue_config:
      capacity: 10000
      min_shards: 2
      max_shards: 30
      max_samples_per_send: 2000
      batch_send_deadline: 5s
    write_relabel_configs:
      - source_labels:
          - __name__
        regex: "debug_.*|test_.*"
        action: drop

C.9 监控 remote_write 状态

prometheus_remote_storage_samples_pending
prometheus_remote_storage_samples_failed_total
prometheus_remote_storage_samples_retried_total
prometheus_remote_storage_succeeded_samples_total
prometheus_remote_storage_dropped_samples_total
prometheus_remote_storage_queue_highest_sent_timestamp_seconds

C.10 常见问题

  • samples_pending 持续增长:发送速度低于采集速度,可能是远端慢、网络慢、限流或队列配置不足。
  • failed_total 增长:远端返回错误,常见于认证失败、限流、请求过大或协议地址错误。
  • retried_total 增长:远端短暂不可用或网络不稳定。
  • highest_sent_timestamp 明显落后当前时间:remote_write 已经产生发送延迟。

附录 D. VictoriaMetrics 接收 remote_write 后 Grafana 如何展示

当 Prometheus 或 Prometheus Agent 通过 remote_write 把指标写入 VictoriaMetrics 后,Grafana 通常不再直接查询采集端 Prometheus,而是把 VictoriaMetrics 的查询接口 配置为 Prometheus 类型数据源。

整体链路:

Application / Exporter
        |
        | scrape
        v
Prometheus / Prometheus Agent
        |
        | remote_write
        v
VictoriaMetrics
        |
        | Prometheus-compatible query API
        v
Grafana
        |
        v
Dashboard / Alerting

关键点:

  • remote_write 负责把数据写入 VictoriaMetrics。
  • Grafana 负责从 VictoriaMetrics 查询数据。
  • Grafana 中的数据源类型选择 Prometheus,不是单独的 VictoriaMetrics 类型。
  • VictoriaMetrics 兼容 Prometheus 查询 API,Grafana 可以使用 PromQL 或 MetricsQL 查询。

D.1 VictoriaMetrics 写入地址与查询地址

VictoriaMetrics 常用两类接口:

用途 接口 谁使用
写入 remote_write 数据 /api/v1/write Prometheus / Prometheus Agent
查询指标数据 /prometheus 或 Prometheus-compatible API Grafana

单机版 VictoriaMetrics 常见地址:

remote_write url: http://victoriametrics:8428/api/v1/write
Grafana datasource url: http://victoriametrics:8428

在 Grafana 中,Prometheus 数据源 URL 通常可以填写:

http://victoriametrics:8428

或:

http://victoriametrics:8428/prometheus

具体使用哪个取决于 VictoriaMetrics 部署方式、代理路径和网关配置。单机版常见做法是直接使用 http://victoriametrics:8428


D.2 Prometheus remote_write 到 VictoriaMetrics

Prometheus Server 配置示例:

global:
  scrape_interval: 15s
  external_labels:
    cluster: prod-a
    env: prod

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

remote_write:
  - url: http://victoriametrics:8428/api/v1/write

Prometheus Agent 配置示例:

global:
  scrape_interval: 15s
  external_labels:
    cluster: prod-a
    env: prod

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

remote_write:
  - url: http://victoriametrics:8428/api/v1/write
    queue_config:
      capacity: 10000
      max_shards: 20
      max_samples_per_send: 2000

如果 VictoriaMetrics 前面有 Nginx、Ingress 或网关,url 应该填写网关暴露的 remote write 地址,例如:

remote_write:
  - url: https://metrics.example.com/api/v1/write
    bearer_token_file: /etc/prometheus/remote-write-token

D.3 Grafana 添加 VictoriaMetrics 数据源

在 Grafana 中进入:

Connections -> Data sources -> Add data source

选择数据源类型:

Prometheus

填写 URL。

Docker Compose 同网络示例:

http://victoriametrics:8428

Kubernetes Service 示例:

http://victoriametrics.monitoring.svc.cluster.local:8428

如果使用 Ingress 或网关:

https://metrics.example.com

保存并测试:

Save & test

测试成功后,Grafana 就可以像查询 Prometheus 一样查询 VictoriaMetrics 中的数据。


D.4 Grafana 数据源配置项建议

Grafana Prometheus 数据源中常见配置建议:

配置项 建议
Data source type Prometheus
URL VictoriaMetrics 查询地址,不是 /api/v1/write 写入地址
Access 通常使用 Server
Scrape interval 与 Prometheus scrape_interval 保持一致,例如 15s
Query timeout 根据查询规模设置,例如 30s60s
HTTP Method 通常使用 POST,复杂查询更稳定

注意:Grafana 的 URL 必须是 查询地址,不能填 remote_write 写入地址。

错误示例:

http://victoriametrics:8428/api/v1/write

正确示例:

http://victoriametrics:8428

D.5 Docker Compose 示例

下面示例展示 Prometheus remote_write 到 VictoriaMetrics,Grafana 查询 VictoriaMetrics。

prometheus.yml

global:
  scrape_interval: 15s
  external_labels:
    cluster: local-demo
    env: dev

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets:
          - prometheus:9090

remote_write:
  - url: http://victoriametrics:8428/api/v1/write

docker-compose.yml

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
    depends_on:
      - victoriametrics

  victoriametrics:
    image: victoriametrics/victoria-metrics:latest
    container_name: victoriametrics
    ports:
      - "8428:8428"
    volumes:
      - victoriametrics-data:/victoria-metrics-data
    command:
      - --storageDataPath=/victoria-metrics-data
      - --retentionPeriod=30d

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - victoriametrics

volumes:
  prometheus-data:
  victoriametrics-data:
  grafana-data:

启动:

docker compose up -d

Grafana 中添加 Prometheus 数据源,URL 填:

http://victoriametrics:8428

然后在 Grafana Explore 中测试:

up

D.6 Kubernetes 场景配置

假设 VictoriaMetrics 部署在 monitoring 命名空间,Service 名称是 victoriametrics,端口是 8428

Prometheus 或 Agent 的 remote_write:

remote_write:
  - url: http://victoriametrics.monitoring.svc.cluster.local:8428/api/v1/write

Grafana 数据源 URL:

http://victoriametrics.monitoring.svc.cluster.local:8428

如果 Grafana 与 VictoriaMetrics 在同一个 namespace,也可以使用短地址:

http://victoriametrics:8428

D.7 Grafana 查询示例

查看采集目标是否正常:

up

查看 Prometheus remote_write 是否成功发送:

rate(prometheus_remote_storage_succeeded_samples_total[5m])

查看 remote_write 待发送样本:

prometheus_remote_storage_samples_pending

查看 HTTP QPS:

sum by (job) (rate(http_requests_total[$__rate_interval]))

查看 5xx 错误率:

sum by (job) (rate(http_requests_total{code=~"5.."}[$__rate_interval]))
/
sum by (job) (rate(http_requests_total[$__rate_interval]))

查看 CPU 使用率:

100 - (
  avg by (instance) (
    rate(node_cpu_seconds_total{mode="idle"}[$__rate_interval])
  ) * 100
)

D.8 使用 VictoriaMetrics Dashboard

Grafana 可以直接复用很多 Prometheus 风格 Dashboard,因为 VictoriaMetrics 兼容 Prometheus 查询 API。

常见方式:

  1. 在 Grafana 中添加 VictoriaMetrics 作为 Prometheus 数据源。
  2. 导入已有 Prometheus Dashboard。
  3. 将 Dashboard 的数据源选择为 VictoriaMetrics 对应的数据源。
  4. 如果查询中使用了 Prometheus 特有但 VictoriaMetrics 表现不同的函数,再逐个调整。

VictoriaMetrics 支持 MetricsQL。MetricsQL 兼容 PromQL,并提供额外能力。一般情况下,原 PromQL 可以直接使用。


D.9 常见问题排查

D.9.1 Grafana Save & test 失败

检查:

  • Grafana 容器或 Pod 是否能访问 VictoriaMetrics Service。
  • Grafana 数据源 URL 是否填成了查询地址,而不是 /api/v1/write
  • VictoriaMetrics 是否监听 8428
  • 如果通过 Ingress 访问,路径是否被正确转发。
  • 如果启用了认证,Grafana 数据源是否配置了对应 Header、Basic Auth 或 Token。

D.9.2 Grafana 能连上,但查不到数据

检查 Prometheus / Agent 是否成功写入 VictoriaMetrics:

prometheus_remote_storage_succeeded_samples_total
prometheus_remote_storage_samples_failed_total
prometheus_remote_storage_samples_pending

也可以直接访问 VictoriaMetrics 查询接口测试:

http://victoriametrics:8428/api/v1/query?query=up

如果 up 没有数据,通常说明:

  • Prometheus 没有抓到目标;
  • remote_write 地址错误;
  • VictoriaMetrics 没收到数据;
  • write_relabel_configs 把指标过滤掉了;
  • 查询时间范围不包含写入数据。

D.9.3 Grafana 查询慢

常见原因:

  • 查询时间范围太大;
  • PromQL 聚合维度太多;
  • 高基数 label 太多;
  • Dashboard 同时发起太多查询;
  • VictoriaMetrics 资源不足。

优化建议:

  • 使用 $__rate_interval 替代固定 [5m]
  • 避免按 podcontainer_idrequest_id 等高基数 label 展示大范围数据。
  • 对常用复杂查询做 recording rules。
  • 缩小 Dashboard 默认时间范围。
  • 为 VictoriaMetrics 配置足够 CPU、内存和磁盘性能。

D.10 最小可用配置总结

Prometheus / Agent 写入 VictoriaMetrics:

remote_write:
  - url: http://victoriametrics:8428/api/v1/write

Grafana 添加数据源:

Type: Prometheus
URL:  http://victoriametrics:8428

Grafana 查询:

up

核心原则:

Prometheus / Agent 使用 /api/v1/write 写入
Grafana 使用 VictoriaMetrics 查询地址读取
Grafana 数据源类型选择 Prometheus

附录 E. 组合使用架构

E.1 单集群基础架构

Long-running Service / Exporter -> Prometheus Server
Batch Job -> Pushgateway -> Prometheus Server
Prometheus Server -> Grafana / Alertmanager

Prometheus 配置示例:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

  - job_name: node
    static_configs:
      - targets:
          - node-exporter:9100

  - job_name: pushgateway
    xxx_labels: true
    static_configs:
      - targets:
          - pushgateway:9091

E.2 多集群中心化架构

Cluster A:
  App / Exporter -> Prometheus Agent
  Batch Job -> Pushgateway -> Prometheus Agent

Cluster B:
  App / Exporter -> Prometheus Agent
  Batch Job -> Pushgateway -> Prometheus Agent

Prometheus Agents -> remote_write -> Mimir / Thanos / VictoriaMetrics -> Grafana / Alerting

Agent 配置示例:

global:
  scrape_interval: 15s
  external_labels:
    cluster: prod-a
    env: prod

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

  - job_name: pushgateway
    xxx_labels: true
    static_configs:
      - targets:
          - pushgateway:9091

remote_write:
  - url: http://mimir-nginx/api/v1/push

附录 F. 常见问题与排查

F.1 Prometheus 抓不到目标

检查目标状态:

Prometheus UI -> Status -> Targets

常见原因:

  • target 地址写错;
  • 网络不通;
  • /metrics path 错误;
  • 服务没有监听对应端口;
  • Kubernetes relabel 规则过滤掉了目标;
  • TLS 或认证配置错误。

F.2 remote_write 堵塞

查看指标:

prometheus_remote_storage_samples_pending
prometheus_remote_storage_samples_failed_total
prometheus_remote_storage_samples_retried_total
prometheus_remote_storage_queue_highest_sent_timestamp_seconds

常见原因:

  • 远端存储不可用;
  • 远端限流;
  • 网络延迟高;
  • 样本量过大;
  • 高基数指标过多;
  • 队列配置不足。

F.3 Pushgateway 指标一直存在

这是 Pushgateway 的正常行为。Pushgateway 不知道任务是否已经消失。

处理方式:

  • 对固定周期任务,使用 last_success_unixtime 判断是否过期;
  • 对一次性任务,任务结束后调用 DELETE;
  • 避免为临时任务生成无限增长的 grouping key。

F.4 Pushgateway 中 job/instance 标签异常

Prometheus 抓取 Pushgateway 时建议配置:

xxx_labels: true

否则 Prometheus 可能改写 jobinstance label。


附录 G. 最佳实践总结

G.1 Prometheus Server

  • 适合完整监控闭环;
  • 负责查询、规则、告警和本地存储;
  • 单实例容量有限,大规模场景需分片或接入远端存储;
  • 生产环境建议配合 Grafana、Alertmanager、Prometheus Operator。

G.2 Prometheus Agent

  • 适合作为采集端;
  • 必须规划 remote_write 后端;
  • 多集群场景必须配置 external_labels
  • 使用 metric_relabel_configs 控制指标量和高基数;
  • WAL 只是缓冲,不是长期存储。

G.3 Pushgateway

  • 只推荐短生命周期任务使用;
  • 不要替代长期服务的 /metrics
  • 使用 xxx_labels: true
  • 通过 last_success_unixtime 监控任务是否按时成功;
  • 避免高基数 grouping key;
  • 对一次性任务及时清理。

附录 H. 快速决策表

需求 推荐组件
监控长期运行 Web 服务 Prometheus Server 或 Prometheus Agent
本地查询 PromQL Prometheus Server
本地告警 Prometheus Server
多集群统一写入中心存储 Prometheus Agent
边缘集群轻量采集 Prometheus Agent
监控 CronJob 最近一次成功 Pushgateway + Prometheus
监控批处理耗时和结果 Pushgateway + Prometheus
长期历史存储和横向扩展查询 Prometheus + Thanos / Mimir / VictoriaMetrics
替代所有服务的指标 push 入口 不建议使用 Pushgateway

附录 I. 最小组合示例

I.1 Prometheus 抓取应用和 Pushgateway

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

  - job_name: pushgateway
    xxx_labels: true
    static_configs:
      - targets:
          - pushgateway:9091

rule_files:
  - alerts.yml

I.2 批任务推送指标

cat <<'EOF' | curl --data-binary @- http://pushgateway:9091/metrics/job/daily_report/env/prod
daily_report_last_success_unixtime 1710000000
daily_report_duration_seconds 42
daily_report_success 1
EOF

I.3 Agent 转发到远端存储

global:
  scrape_interval: 15s
  external_labels:
    cluster: prod-a
    env: prod

scrape_configs:
  - job_name: app
    static_configs:
      - targets:
          - app:8080

  - job_name: pushgateway
    xxx_labels: true
    static_configs:
      - targets:
          - pushgateway:9091

remote_write:
  - url: http://remote-storage/api/v1/write

启动 Agent:

prometheus \
  --config.file=prometheus-agent.yml \
  --agent \
  --storage.agent.path=./agent-data

附录 J. 总结:Prometheus、Grafana、PromQL

Prometheus 与 Grafana 的配合方式:

Prometheus 负责采集、存储和查询指标
Grafana 负责可视化、仪表盘和分析展示
PromQL 是 Prometheus 与 Grafana 之间最核心的查询语言

最常用 PromQL 模板:

up
rate(xxx_total[5m])
sum by (job) (rate(xxx_total[5m]))
increase(xxx_total[1h])
histogram_quantile(0.95, sum by (le) (rate(xxx_bucket[5m])))
sum(rate(http_requests_total{code=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
posted @ 2026-07-19 20:43  技术摘抄  阅读(10)  评论(0)    收藏  举报