兄弟们,Prometheus 告警规则这玩意儿,看着简单,真上线了全是坑。
我见过太多团队,规则写了几百条,结果 PagerDuty 半夜疯狂报警,第二天一看全是噪音。或者反过来——集群都挂了十分钟了,告警邮件还在路上慢悠悠地飘。
2026 年了,Prometheus 生态早就不只是“装个 Server + Alertmanager”那么简单了。今天这篇,我就把生产环境里真正能用、能扛、不翻车的告警规则配置经验,掰开了揉碎了讲清楚。
别指望抄一份规则就万事大吉。 每家的业务、流量模型、基础设施都不一样。但底层的原则和套路,是通用的。
先搞清楚:告警规则到底怎么写?
Prometheus 的告警规则,核心就是一段 PromQL 表达式。表达式算出来是 true,告警就触发。
一个标准的规则文件长这样:
groups:
- name: example
rules:
- alert: HighRequestLatency
expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: critical
annotations:
summary: "High request latency on {{ $labels.instance }}"
description: "{{ $labels.instance }} has a 99th percentile latency of {{ $value }}s (threshold: 1s)"
这里有几个关键点:
expr:这是灵魂。表达式写不对,后面全白搭。for:这是防抖神器。条件满足后,持续多久才真正触发告警。千万别设成 0,除非你想被高频抖动炸死。labels和annotations:这是告警的“元数据”。labels用于路由(比如分给哪个团队),annotations是给人看的描述信息。
核心配置步骤:从 0 到 1
假设你已经有一个跑起来的 Prometheus 实例。没有的话,先去装一个,这步不展开了。
第一步:创建规则文件
在 Prometheus 服务器上,创建一个目录,比如 /etc/prometheus/rules/。里面放你的 .yml 或 .yaml 文件。
第二步:告诉 Prometheus 去哪找规则
修改你的 prometheus.yml,在 rule_files 字段里指定路径:
rule_files:
- "/etc/prometheus/rules/*.yml"
- "/etc/prometheus/rules/*.yaml"
第三步:重载配置
发一个 SIGHUP 信号给 Prometheus 进程,或者用 API 热重载:
curl -X POST http://localhost:9090/-/reload
第四步:验证规则
在 Prometheus UI 的 Alerts 页面,能看到所有加载的规则和它们的状态。如果规则语法有问题,Prometheus 启动时会报错,日志里会告诉你哪一行写错了。
第五步:配置 Alertmanager
规则只负责“触发告警”,真正“发送通知”的是 Alertmanager。你需要在 Alertmanager 的配置文件里定义路由和接收器(比如 Slack、邮件、PagerDuty)。
2026 年必须掌握的进阶技巧
基础操作谁都会。下面这几个,才是真正能让你从“能用”变成“好用”的关键。
1. Recording Rules:给告警规则“减负”
复杂告警规则里的那些聚合查询(比如 histogram_quantile),每次计算都很重。如果多个规则复用同一个聚合,Prometheus 就得重复算好几次,压力山大。
Recording Rules 就是干这个的:提前算好,存成一个新的时间序列。
groups:
- name: recording_rules
rules:
- record: job:http_request_latency_seconds:99quantile5m
expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
然后告警规则里直接引用:
- alert: HighRequestLatency
expr: job:http_request_latency_seconds:99quantile5m > 1
效果:把计算前置到采集阶段,告警查询几乎是零成本。我们团队把 P99 告警的查询时间从 800ms 降到了 10ms 以下。
2. 用 for 和 keep_firing_for 控制告警生命周期
for 是“持续多久才触发”,keep_firing_for 是“条件恢复后,告警再保留多久”。
这俩组合起来,能解决一个经典问题:告警风暴。
比如,你的服务重启了,监控指标瞬间变成 0,然后又恢复正常。如果没有 for,你会收到一条“服务挂了”的告警,紧接着一条“服务恢复”的告警。如果 keep_firing_for 设置得当,你可以让告警在问题真正稳定后再消失,避免来回刷屏。
3. 告警分组与抑制:别让 Alertmanager 炸掉
Alertmanager 的 group_by 和 group_wait 参数,是控制告警聚合的关键。
route:
group_by: ['alertname', 'cluster']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
group_by:按什么维度分组。比如按alertname和cluster分组,同一个集群的同一个告警只会发一条通知。group_wait:第一批通知的等待时间。比如 30 秒内触发的同组告警,会合并成一条发送。repeat_interval:告警持续未解决时,多久重复通知一次。设长一点,4 小时一次足够了,没人想每 5 分钟被同一个告警轰炸。
最佳实践速查表
| 实践 | 说明 | 推荐配置 |
|---|---|---|
for 时长 | 防抖动,避免瞬时波动触发告警 | 关键指标(如 CPU):2-5m;次要指标:10-15m |
repeat_interval | 避免告警轰炸 | 4h+ |
| Recording Rules | 预计算复杂聚合,降低告警查询开销 | 对 histogram_quantile、rate 等复杂查询使用 |
| 告警分组 | 按 alertname、cluster 等维度分组 | group_by: ['alertname', 'cluster'] |
| 告警抑制 | 父告警触发时,抑制子告警 | 在 Alertmanager 中配置 inhibit_rules |
| 标签标准化 | 确保告警标签一致,便于路由和聚合 | 统一使用 severity、team、service 等标签 |
| 告警文档化 | 在 annotations 中写清楚排查步骤 | 包含 runbook_url、summary、description |
常见坑与解决方案
- 坑一:告警规则太多,Prometheus 内存爆了。 解:减少规则数量,多用 Recording Rules 预计算。
- 坑二:Alertmanager 收到告警但没发出通知。 解:检查 Alertmanager 日志,确认路由配置是否匹配了告警的
labels。 - 坑三:告警重复发送。 解:检查
group_interval和repeat_interval设置,确认 Alertmanager 的repeat_interval大于group_interval。
FAQ
Q: Prometheus 告警规则和 Alertmanager 的区别是什么? A: Prometheus 负责评估规则,触发告警。Alertmanager 负责接收告警,进行分组、抑制、去重,并发送通知。两者是独立的组件。
Q: 如何测试告警规则?
A: 可以使用 promtool 工具。运行 promtool check rules /path/to/rules.yml 检查语法。也可以使用 promtool test rules 进行单元测试。
Q: for: 5m 是什么意思?
A: 表示 PromQL 表达式结果持续为 true 达到 5 分钟后,告警才会触发。这可以防止因瞬时波动导致的误报。
Q: 告警规则中的 labels 和 annotations 有什么区别?
A: labels 是标签,用于告警路由、分组和抑制。annotations 是注解,用于提供告警的详细信息,如描述、摘要、Runbook 链接等。
Q: 如何避免告警风暴?
A: 使用 for 防抖动、group_by 分组、inhibit_rules 抑制、以及设置合理的 repeat_interval。
社区灵感与参考 (References & Community Insights)
本文探讨的架构演进与技术实现方案,深度提炼自 Hacker News、Reddit 等极客社区的真实工程师讨论、线上事故复盘(Post-mortems)以及一线技术博客的实战经验分享。