
Prometheus 自 2012 年由 SoundCloud 开源以来,已成为云原生监控领域的事实标准。它基于 多维数据模型 和 灵活查询语言(PromQL) 的设计,使其在动态微服务环境中表现得游刃有余。2016 年,Prometheus 加入 CNCF,成为继 Kubernetes 之后第二个毕业的项目。
本文将从架构原理出发,深入剖析 Prometheus 的核心组件、数据模型、服务发现机制、PromQL 高级用法、告警优化以及高可用方案,并结合实践案例,帮助读者构建一套可靠、可扩展的监控体系。
Prometheus 采用 拉取(Pull) 模型采集指标,这与传统的 Push 模型(如 Zabbix)形成鲜明对比。Pull 模型带来了以下优势:
典型架构包含以下组件:
+----------------+ +-----------------+ +-----------------+
| Exporters |----> | Prometheus |----> | Alertmanager |
| (Node/App) | | Server | | (告警分组/抑制) |
+----------------+ +-----------------+ +-----------------+
| | |
v v v
+----------------+ +-----------------+ +-----------------+
| Pushgateway | | TSDB (本地) | | 接收者 |
| (短期任务) | +-----------------+ | (Email/Webhook)|
+----------------+ | +-----------------+
v
+-----------------+
| Remote Storage |
| (Thanos/Cortex) |
+-----------------+数据流简述:
/metrics 端点暴露指标(或使用 Exporters)。scrape_configs 定时拉取。Prometheus 的数据模型建立在 时序(Time Series) 之上,每条时序由 指标名称(Metric Name) 和 标签键值对(Labels) 唯一标识。
例如:
http_requests_total{method="GET", endpoint="/api", status="200"} 12345http_requests_total)。类型 | 描述 | 适用场景 |
|---|---|---|
Counter | 单调递增的累计值,只增不减(重启后重置)。 | 请求总数、错误总数、处理字节数 |
Gauge | 可任意增减的瞬时值。 | CPU 使用率、内存占用、队列长度 |
Histogram | 对观测值进行采样,生成桶计数和总和。可用于计算分位数。 | 请求延迟、响应大小分布 |
Summary | 类似于 Histogram,但分位数在客户端计算,无法聚合。 | 需精确分位数且客户端支持聚合 |
最佳实践:
_total 后缀(如 requests_total)。_seconds)或字节(_bytes),便于 PromQL 的 rate() 等函数自动理解。Prometheus 支持多种服务发现机制,以动态感知监控目标。
最简单的方式,适用于固定 IP:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['192.168.1.10:9100', '192.168.1.11:9100']适用于配置中心或自定义脚本生成目标列表:
scrape_configs:
- job_name: 'app'
file_sd_configs:
- files:
- '/etc/prometheus/targets/*.json'
refresh_interval: 30stargets.json 示例:
[
{"targets": ["app1:8080"], "labels": {"env": "prod"}}
]Prometheus 原生支持 Kubernetes 的多种角色(node, pod, service, endpoints 等),自动监听 API Server 变化。
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__通过 relabel_configs 可以动态调整标签,为时序添加更丰富的上下文(如 namespace、pod 等)。
PromQL 是 Prometheus 的查询语言,其功能强大但学习曲线略陡。以下重点介绍常用的聚合、运算及预测函数。
http_requests_total{method="GET"}http_requests_total{method="GET"}[5m]http_requests_total{method="GET"} offset 1h常用 sum()、avg()、max()、topk()、count() 等,配合 by 或 without 进行维度裁剪。
示例:计算每个 endpoint 的 QPS(每秒请求数)
sum(rate(http_requests_total[5m])) by (endpoint)示例:找出延迟最高的前 3 个实例
topk(3, avg(histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, instance))) by (instance))rate() vs irate()
rate() 计算指定时间窗口内的平均速率,适合长期趋势(平滑)。irate() 计算最后两个样本点的瞬时速率,适合突增检测(更灵敏)。increase():计算区间内的增量,等同于 rate() * 时间窗口秒数。predict_linear():基于简单线性回归预测未来值,常用于容量规划。predict_linear(node_filesystem_free_bytes{mountpoint="/"}[1h], 4 * 3600)预测 4 小时后磁盘剩余空间。
histogram_quantile():从 Histogram 桶中计算分位数(需注意 le 标签的排序)。对于需要先计算范围向量再聚合的场景,子查询十分有用。例如,计算过去 1 小时每 5 分钟的 QPS 平均值:
avg_over_time(rate(http_requests_total[5m])[1h:5m])告警规则在 Prometheus Server 中评估,触发后通过 HTTP 推送至 Alertmanager。Alertmanager 负责分组(Group)、抑制(Inhibit)、静默(Silence) 和路由。
groups:
- name: instance_status
rules:
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "Job {{ $labels.job }} has been down for more than 1 minute."for 持续时间防止瞬时抖动。annotations 用于提供告警附加信息,支持模板。route:
group_by: ['alertname', 'cluster']
group_wait: 10s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'pagerduty'
continue: true
- match:
severity: warning
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'ops@example.com'Prometheus 默认使用本地磁盘存储,支持压缩和指数退避写入,但存在以下问题:
Prometheus 通过 --enable-feature=remote-write-receiver 和配置 remote_write 实现与外部存储对接。
主流方案对比:
方案 | 架构特点 | 适用场景 |
|---|---|---|
Thanos | Sidecar 模式,利用对象存储(S3/GCS)实现长期存储,支持全局查询和去重。 | 已有 Prometheus 集群,需长期存储和高可用。 |
Cortex | 微服务架构,支持租户隔离,水平扩展能力强。 | 多租户、大规模场景(如 SaaS)。 |
VictoriaMetrics | 单二进制,高性能,兼容 Prometheus 远程协议。 | 中小规模,性能敏感。 |
Mimir | Cortex 的继任者,简化架构,同样支持多租户。 | 同 Cortex,但更成熟运维简单。 |
推荐:使用 Thanos 或 Mimir 构建高可用、长期存储的监控体系。
例如,监控一个 Web 服务:
rate(http_requests_total[5m])rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))app_、node_、db_。user_id、email),以免造成 TSDB 膨胀。若确实需要,可考虑使用日志系统替代。scrape_interval 和 evaluation_interval,避免过于频繁。sample_limit 限制每个目标的最大样本数,防止恶意或异常指标拖垮 Prometheus。在 Spring Boot 中引入 micrometer-registry-prometheus,配置 management.endpoints.web.exposure.include=prometheus,即可通过 /actuator/prometheus 获取标准指标(JVM、HTTP 请求等)。
scrape_configs:
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app-service:8080']JVM (Micrometer) 官方 Dashboard,导入 ID 4701。sum(rate(order_created_total[5m])) / sum(rate(order_attempted_total[5m]))- alert: HighErrorRate
expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[2m])) / sum(rate(http_server_requests_seconds_count[2m])) > 0.05
for: 3m
labels:
severity: warning
annotations:
summary: "Error rate above 5%"Prometheus 凭借其简洁而强大的设计,已成为云原生监控生态的中枢。理解其核心模型、查询语言和告警机制,是构建可靠可观测性系统的基础。在实际生产中,结合 Thanos/Mimir 解决存储和高可用问题,并遵循 USE/RED 等最佳实践,能够显著提升系统的可维护性和故障响应效率。
监控不是终点,而是持续优化的起点。希望本文能帮助读者深入掌握 Prometheus,并灵活运用于自己的技术栈中。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。