告警风暴一来,真正的故障反而被淹没。运维不是不需要告警,而是需要"有效告警"。
痛点:告警太多 = 没有告警
场景很熟悉:Prometheus + Alertmanager 部署完毕,规则写了几十条,结果每天收到上百条通知——CPU 短暂飙高、磁盘波动、网络抖动……真正的故障告警混在噪音里,值班同学看到通知直接划掉,形成"狼来了"效应。
某团队统计过:80% 的告警在 5 分钟内自动恢复,真正需要人工介入的不到 10%。问题不在 Prometheus 不好用,而在告警规则和 Alertmanager 路由没调好。
方案:5 步降噪,只保留有价值的告警
核心思路:抬高触发门槛 + 智能分组 + 抑制联动 + 静默窗口 + 分级路由。
实操步骤
第 1 招:用 for 过滤瞬时抖动
90% 的噪音来自瞬时波动。一条 for: 5m 就能干掉大量无意义告警:
# prometheus/rules/node.yml
groups:
- name: node-alerts
rules:
- alert: HighCpuUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 10m # 持续 10 分钟才触发,过滤短暂毛刺
labels:
severity: warning
annotations:
summary: "CPU 持续高负载 {{ $labels.instance }}"
value: "{{ $value | printf \"%.1f\" }}%"
经验值:
- CPU / 内存告警:for: 10m
- 磁盘空间:for: 5m
- 服务不可达:for: 2m(这个不能太长,否则影响 MTTR)
第 2 招:Alertmanager 分组聚合
同一批机器同时挂了 10 台,你不需要收 10 条通知。用 group_by 聚合:
# alertmanager.yml
route:
receiver: default
group_by: ['alertname', 'cluster']
group_wait: 30s # 等 30 秒收集同类告警
group_interval: 5m # 同组告警合并发送间隔
repeat_interval: 4h # 未恢复告警重复通知间隔(别设太短!)
repeat_interval 是降噪关键——设成 1m 等于自己给自己搞 DDoS。建议 warning 设 4h,critical 设 1h。
第 3 招:inhibit_rules 抑制关联告警
节点宕机了,上面跑的服务肯定也挂。不需要同时收到"节点不可达"和"服务 5xx 飙升"两条告警:
# alertmanager.yml
inhibit_rules:
- source_match:
alertname: NodeDown
target_match_re:
alertname: '(HighErrorRate|ServiceUnavailable|HighLatency)'
equal: ['instance']
当 NodeDown 触发时,自动抑制同一 instance 上的服务级告警,只发根因通知。
第 4 招:time_intervals 静默维护窗口
每周二凌晨有批量更新?提前配置静默,不用手动 silence:
# alertmanager.yml
time_intervals:
- name: maintenance-window
time_intervals:
- weekdays: ['tuesday']
times:
- start_time: '02:00'
end_time: '04:00'
route:
routes:
- match:
severity: warning
mute_time_intervals:
- maintenance-window
注意:critical 级别不建议静默——维护窗口也可能出真故障。
第 5 招:分级路由,该叫谁叫谁
不是所有告警都需要发到钉钉群。按严重级别分流:
route:
receiver: default
routes:
- match:
severity: critical
receiver: pagerduty-oncall # 电话 + 短信,必须响应
repeat_interval: 30m
- match:
severity: warning
receiver: dingtalk-ops # 钉钉群,工作时间处理
repeat_interval: 4h
- match:
severity: info
receiver: slack-log # 仅记录,不打扰
repeat_interval: 12h
3 个常见坑
坑 1:for 设太长导致漏报
磁盘快满设了 for: 30m,结果写满了才告警。磁盘类告警建议 for: 5m,同时加一条 predict_linear 预测规则:
- alert: DiskWillFull24h
expr: predict_linear(node_filesystem_avail_bytes{fstype!="tmpfs"}[6h], 24*3600) < 0
for: 10m
labels:
severity: warning
坑 2:group_by 用了太多 label
group_by: ['alertname', 'instance', 'job', 'env'] ——分得太细等于没分组,每台机器单独一条。通常 ['alertname', 'cluster'] 或 ['alertname', 'env'] 就够了。
坑 3:repeat_interval 设太短被通知轰炸
默认值是 4h,有人改成 5m 想"确保不漏",结果一个未恢复的告警一天发了 288 条。warning 用 4h,critical 用 1h,足够了。
总结
降噪五步:
for过滤瞬时:大多数告警加 5-10 分钟持续条件group_by聚合:同类告警合并,减少通知条数inhibit_rules抑制:根因告警触发时,自动压制衍生告警time_intervals静默:维护窗口自动 mute- 分级路由:critical 叫人,warning 群通知,info 只记日志
做完这五步,告警量通常能降 60%-80%,剩下的每一条都值得看。告警系统的目标不是"全覆盖",而是"每条都有人响应"。