告警一条接一条刷屏?五步治理告警风暴

故障只持续了 5 分钟,手机却响了 200 次。值班群里"滴滴"声此起彼伏,等真正要动手时,已经没人看得清哪一条才是根因。告警风暴不是告警系统坏了,而是规则设计和依赖关系从来没被梳理过。

一、先判断:是"故障多"还是"告警风暴"

三个特征只要中两个,就是风暴:

  1. 同一分钟内爆发成百条,而不是零星几条;
  2. alertname 高度雷同,同一个指标在几十个实例上一起喊;
  3. 上游只有一条告警,下游一片红,根因数远小于告警数。

一句话判据:根因数 << 告警条数。

快速取证,先看谁是"告警大户":

bash 复制代码
# 当前生效告警按名字聚合,看谁贡献最多条
curl -s localhost:9093/api/v2/alerts \
  | jq -r '.[].labels.alertname' | sort | uniq -c | sort -rn | head

# 看它们是不是同一时间窗爆发
curl -s localhost:9093/api/v2/alerts \
  | jq -r '.[].startsAt' | cut -c1-16 | sort | uniq -c

二、第 1 步:给规则加"持续时长",滤掉抖动

for 是最便宜的降噪开关。瞬时毛刺不该惊动人:

yaml 复制代码
groups:
- name: node
  rules:
  - alert: NodeCPUHigh
    expr: 100 - (avg by(instance)
           (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
    for: 10m          # 持续 10 分钟才发,抖动自动滤掉
    labels: { severity: warning }
    annotations:
      summary: "{{ $labels.instance }} CPU 持续高于 90%"

同时要问自己:expr 表达的是"机器累了"还是"用户不能用了"?CPU 打到 90% 不是故障,接口错误率上升才是。

三、第 2 步:分组与抑制,让同一件事只响一次

分组 把同源告警合并成一条通知,抑制让上游故障出现时下游闭嘴:

yaml 复制代码
route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s        # 首次等待,攒一批再发,别设太小
  group_interval: 5m     # 同组有新告警时的合并间隔
  repeat_interval: 4h    # 未恢复告警的重发间隔,别设 5m

inhibit_rules:
- source_match: { severity: 'critical' }   # 上游:节点/机房级故障
  target_match: { severity: 'warning' }    # 下游:被它带崩的实例告警
  equal: ['cluster', 'instance']

抑制的含义是"源故障出现时,压制目标告警"。方向写反,真故障会被压住------这是最危险的一类配置错误。

四、第 3 步:分级路由,重要的才喊醒人

把告警当人来看待,按"要不要半夜叫醒值班"分级:

yaml 复制代码
routes:
- matchers: [ severity="critical" ]
  receiver: pager            # 电话/短信,必须有人到
- matchers: [ severity="warning" ]
  receiver: im-group         # 群消息,工作时间处理
  repeat_interval: 6h

反模式很常见:所有告警都投到同一个 500 人大群。结果全员开启免打扰,真故障没人看,这就是告警疲劳。趋势类、容量类的信息应该进日报和看板,不进人。

五、第 4 步:从"监控资源"转向"监控症状"

最吵的一类规则往往长这样:磁盘 80%、CPU 90%、内存 85%。它们既不代表故障,也回答不了"我该做什么"。

两条改造思路:

  • 换成 RED / USE 方法:请求错误率、延迟、资源饱和度。对"用户能不能用"告警,而不是对"机器累不累"告警。
  • 阈值告警改趋势告警:不要等磁盘满了才喊,提前预测:
promql 复制代码
# 按近 6 小时趋势,预测 4 小时内将写满 → 有缓冲时间,不慌
predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*3600) < 0

六、第 5 步:闭环------每次风暴都要复盘

  • 记录四个数:告警总条数、去重后条数、MTTA(响应时长)、误报条数;
  • 每月清理一次规则:3 个月没触发过、每次都误报、没人认领动作的规则直接删掉;
  • 做一次故障注入演练(kill 一个实例、断开一条依赖),看告警是否符合预期------静默的监控比没有监控更危险;
  • 给告警链路本身加自检:Watchdog 心跳告警,收到才说明"没有告警"是真的没故障,而不是管道断了。

七、避坑清单

  1. for: 0s 是风暴的头号制造者,任何瞬时告警都会成灾。
  2. group_wait 太短 → 每条一个通知;太长 → P0 迟到。从 30s 起步调。
  3. repeat_interval 用 5m → 未恢复的告警每 5 分钟重来一遍,等于自己造风暴。
  4. 抑制规则方向写反 → 真故障被压住,比不告警更危险。
  5. 用邮件当 P0 通道 → 没人看,等于没有告警。
  6. 测试环境告警发到生产群 → 天天"狼来了",很快就没人信。
  7. 只想删告警、不愿改规则 → 下次故障照样刷屏。
  8. 忽略告警疲劳:人一旦开始忽略告警,整套监控就失效了------降噪和加监控同样重要。

八、一图总结

复制代码
先算根因数  →  加 for 时长  →  抑制分组去重  →  分级路由派人  →  复盘清理规则
(风暴定性)    (滤抖动)      (同一事一声)   (P0 电话 P2 日报)  (删误报)

小结 :告警的价值不在于"发得多",而在于"发了就一定有人动"。先算根因数、再加 for 时长、用抑制和分组去重、按级别选通道、每月复盘清理规则------五步走完,手机能安静下来,而真故障一条都跑不掉。

相关推荐
帷幕落秋1 小时前
Docker镜像加速
运维·docker
帷幕落秋1 小时前
Docker原理-理论基础
运维·docker
有毒的教程1 小时前
Linux底层存储路由配
linux·运维·网络
云智慧AIOps社区2 小时前
MSP 的增长瓶颈不在客户,在交付模式:人效与规模如何兼得?
运维·人工智能·自动化运维
HAHAXX83 小时前
淘宝RPA定时拉取交易数据实战:从人工录单报错到自动化对账全流程复盘
运维·自动化·rpa
Coisinier4 小时前
docker命令管理镜像及容器
linux·运维·nginx·docker·容器·操作系统
fengkai45454 小时前
十三、Zabbix 监控
运维·服务器·zabbix·监控·网络设备
古法老登瞎折腾4 小时前
大数据智能运维实战(二):准备一个可复现的运维实验环境
java·大数据·运维·spring ai·mcp
数据中心的那点事儿5 小时前
艾特网能:GPU算力服务器冷却系统配套设计介绍
运维·服务器·gpu算力