兄弟们,今天聊聊Prometheus告警规则。
这东西看着简单,不就是写个PromQL吗?但真到了生产环境,你会发现——告警规则写得烂,比没写还可怕。凌晨三点被无关告警叫醒的感觉,懂的都懂。
我接手过一个系统,光是CPUUsageHigh的告警规则就有7条,互相覆盖、阈值混乱。最后我全删了,从零重写。今天把这些经验倒出来,希望能帮你少踩坑。
核心原则:告警不是监控
这是最大的误区。很多人把Prometheus当监控面板用,恨不得每个指标都配个告警。
Stop it.
告警的目的是让人采取行动。如果收到告警但无事可做,那就是垃圾告警。
我团队内部有个硬性规定:每条告警规则必须附带一个runbook_url label,指向具体的操作文档。写不出runbook的告警规则,不准上线。
怎么写一条合格的告警规则?
先看个反面教材:
groups:
- name: bad_examples
rules:
- alert: HighCPU
expr: avg(rate(node_cpu_seconds_total{mode="user"}[5m])) > 0.9
for: 1m
labels:
severity: critical
annotations:
summary: "CPU is high"
这条规则的问题多了去了:
- 阈值写死,不考虑机器规格差异
- 1分钟的
for太短,瞬间抖动就告警 - 告警信息等于没写,收到告警根本不知道哪台机器出了问题
改一下:
groups:
- name: node_alerts
rules:
- alert: NodeCPUUsageHigh
expr: |
(
1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)
) > 0.9
for: 5m
labels:
severity: warning
team: infra
annotations:
summary: "Node {{ $labels.instance }} CPU usage > 90%"
description: "CPU usage on {{ $labels.instance }} has been at {{ $value | humanizePercentage }} for more than 5 minutes."
runbook_url: "https://wiki.ourteam.com/runbooks/node-high-cpu"
这里做了几件事:
- 用
by (instance)保留实例信息 - 拉长
for到5分钟,滤掉毛刺 - 告警信息里带上实例名和具体数值
- 加了个
teamlabel,方便Alertmanager路由
告警命名的艺术
我见过最离谱的命名是Alert_1、Alert_2… 这种命名等于告诉所有人:我不在乎我的系统。
命名规则我们内部是这样定的:
| 组件 | 命名格式 | 示例 |
|---|---|---|
| 节点 | Node<Metric><Condition> | NodeDiskSpaceFull |
| 容器 | Container<Metric><Condition> | ContainerOOMKilled |
| 应用 | <AppName><Metric><Condition> | APIServerLatencyHigh |
| 业务 | Business<Metric><Condition> | BusinessOrderFailureSpike |
命名要包含三要素:什么组件 + 什么指标 + 什么异常。
告警严重级别怎么定?
别把所有问题都标成critical。我见过一个团队,90%的告警都是critical。结果呢?没人看,真正的critical反而被淹没了。
我们用的是三级制:
| 级别 | 含义 | 响应时间 | 示例 |
|---|---|---|---|
critical | 服务不可用或数据丢失 | 立即响应,15分钟内 | 磁盘写不进去了,API全挂 |
warning | 服务质量下降,但还能用 | 工作时间1小时内 | P99延迟翻倍,但还在SLA内 |
info | 需要关注,但不用立即处理 | 无 | 证书30天后过期 |
关键点:critical一定要和for配合使用。我见过有人设for: 0s的critical告警,结果网络抖动一下,全员被叫醒。
常见踩坑现场
1. 聚合粒度搞错
# 错误:这告警的是集群整体CPU,但你不知道是哪台机器
expr: avg(node_cpu_seconds_total) > 0.9
# 正确:按实例聚合
expr: avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) < 0.1
2. 忘记处理重启后的指标重置
计数器类型的指标(比如http_requests_total)在进程重启后会重置。直接用rate或increase可以避免这个问题,但如果你用delta,就要小心了。
# 错误:进程重启后可能触发假告警
expr: delta(http_requests_total[5m]) < 0
# 正确:用rate,它会正确处理重置
expr: rate(http_requests_total[5m]) < 0.01
3. 告警沉默(Alert Fatigue)
这是最致命的。告警太多 -> 没人看 -> 真出事时错过 -> 系统崩了。
解决方案:定期做告警审计。我每季度做一次,把所有告警规则的触发次数和响应情况拉出来看。触发次数多但没人响应的规则,要么删掉,要么降低级别。
高级技巧:用Recording Rules预计算
如果你的告警规则涉及复杂的聚合计算,别让每次评估都重新算。用Recording Rules预计算:
groups:
- name: recording_rules
rules:
- record: job:node_cpu_usage:avg_5m
expr: avg by(job) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
- name: alert_rules
rules:
- alert: NodeCPUUsageHigh
expr: (1 - job:node_cpu_usage:avg_5m) > 0.9
for: 5m
这样做的好处:
- 减少Prometheus的计算压力
- 告警规则更简洁
- 可以在Grafana里复用同一个指标
告警规则测试
别以为写好了就完事了。Prometheus 2.28+支持promtool测试告警规则:
# test_rule.yaml
rule_files:
- alerts.yml
evaluation_interval: 1m
tests:
- interval: 1m
input_series:
- series: 'node_cpu_seconds_total{instance="node1",mode="idle"}'
values: '0 0 0 0 0' # 5分钟都是0,说明CPU 100%繁忙
alert_rule_test:
- eval_time: 5m
alertname: NodeCPUUsageHigh
exp_alerts:
- exp_labels:
severity: warning
instance: node1
exp_annotations:
summary: "Node node1 CPU usage > 90%"
运行测试:
promtool test rules test_rule.yaml
这个步骤被99%的团队忽略了。我敢说,没经过测试的告警规则,上线后大概率会出事。
最佳实践总结表
| 实践 | 说明 | 推荐度 |
|---|---|---|
| 告警要有runbook | 每条规则必须有对应的操作文档 | ⭐⭐⭐⭐⭐ |
合理使用for | 至少2-5分钟,避免毛刺 | ⭐⭐⭐⭐⭐ |
| 命名规范统一 | 组件+指标+异常 | ⭐⭐⭐⭐ |
| 告警级别分级 | 别让critical泛滥 | ⭐⭐⭐⭐⭐ |
| 用Recording Rules预计算 | 减轻Prometheus压力 | ⭐⭐⭐⭐ |
| 定期审计告警 | 清理无效规则 | ⭐⭐⭐⭐⭐ |
| 测试告警规则 | 用promtool验证 | ⭐⭐⭐⭐ |
| 避免告警信息为空 | 带上实例和具体数值 | ⭐⭐⭐⭐⭐ |
FAQ
Q: 告警规则太多怎么办?
A: 做告警聚合。把类似的告警合并成一条,比如把DiskUsageHigh和InodeUsageHigh合并成StorageUsageHigh,在描述里区分具体问题。我们团队从120条规则砍到了45条,告警噪音下降了70%。
Q: for参数设多久合适?
A: 取决于场景。基础设施告警(CPU、内存)建议5-10分钟;应用层面的告警(错误率、延迟)可以短一些,2-3分钟。核心原则:宁可慢报,不要误报。
Q: 怎么处理重复告警?
A: 利用Alertmanager的group_by和repeat_interval。相同的告警聚合发送,重复的告警不要频繁发。我一般设repeat_interval: 4h,意思是同一个告警如果没解决,4小时后才再次提醒。
Q: 阈值怎么定才合理?
A: 别拍脑袋。先收集两周的基线数据,看正常情况下的P99和P95值。然后基于这些数据设定阈值。我见过最离谱的是把CPU阈值设为5%,结果天天告警——那台机器本来就跑着高负载任务。
告警规则写得好不好,直接决定你晚上能不能睡个好觉。别等到凌晨三点被叫醒才后悔。
有问题欢迎留言,我们评论区见。