运维工程师告警治理实战:从每天800条告警降到57条,我踩过的坑

🔑 关键词:运维工程师,告警治理,Prometheus,Zabbix,可观测性

📖 摘要:一个干了8年运维的人,讲自己怎么把每天800多条告警压到57条,顺带聊聊为什么我认为自动化工具解决不了事故现场90%的问题。含可直接抄的Prometheus/Alertmanager配置参数和一段真实翻车经历。

先说结论:我们组现在的告警量是 57 条/天,2021 年同期是 800 多条。这不是因为把阈值调宽了——恰恰相反,P0 的阈值比三年前更严。变的只是我们判断什么该吵醒人。

图片

我是怎么被 Zabbix 逼疯的

2019 年我在一家做 SaaS 的公司,主机 180 台,Zabbix 4.0,监控模板是当年从 GitHub 上抄来的。触发器一共 312 个。真实场景是:凌晨 2 点 14 分,手机响,内容是「CPU 使用率超过 80% 持续 5 分钟」。我爬起来 SSH 上去,top 一开,是 mysqldump 在跑。每周三凌晨都这样,一周至少折腾三次。

我把这事跟 leader 说了,他回我一句「你先加个 5 分钟的延迟吧」。我就去改了宏,把 {$CPU.UTIL.MAX} 从 80 调成 85。现在回头看,这是最典型的掩耳盗铃。真正的转折点是我干了一件很土的事——统计。直接连 Zabbix 的 MySQL,捞 events 表(这表是真大,记得加索引或者限制时间范围):

图片

SELECT t.description, COUNT(*) c
FROM events e
JOIN triggers t ON e.objectid = t.triggerid
WHERE e.clock > UNIX_TIMESTAMP(NOW() - INTERVAL 30 DAY)
GROUP BY t.description ORDER BY c DESC LIMIT 30;

结果出来我愣了:68% 的告警来自 12 个触发器。CPU、磁盘使用率、内存,还有几个我自己都忘了什么时候加的「进程数少于 1」。而真正能反映用户受损的指标,只有 3 个。那天晚上我把 12 个触发器全删了 9 个,世界安静了一半。

自动化和可观测性,是两件不同的事

图片

这是我干这行 8 年最想说的一个观点:Ansible、SaltStack、Jenkins 这些东西解决的是「怎么做」,但事故现场 90% 的时间花在「为什么」。

举个例子。net.core.somaxconn 默认 128 太小,Nginx 的 backlog 默认 511,高并发下 SYN 队列会直接溢出。用 Ansible 改这个,一行就写完了:

- name: tune somaxconn
  sysctl: name=net.core.somaxconn value=65535 state=present reload=yes

图片

执行 3 秒,200 台机器一次搞定,看起来特别爽。但问题是——如果我不知道有 TcpExtListenDrops 这个计数器,我根本不会去搜这个参数。我当初是怎么发现的?某次大促压测,ss -s 输出里出现 'SYNs to LISTEN sockets dropped',我才顺着 nstat -az | grep -i listen 查到 TcpExtListenDrops 每分钟涨 2000 多,把 tcp_max_syn_backlog 一起调到 65535 才压下去。

所以我的结论有点反常识:自动化给你的是执行速度,可观测性给你的是问题定义权。执行慢一点最多是多加班,定义错了就是白干一整个季度。这就是为什么我不太推荐初级运维一上来就猛啃 Terraform。

我们现在的具体配置(可直接抄)

图片

  • node_exporter 1.7.0,抓取间隔 15s,rule evaluation interval 1m
  • Prometheus 2.48 本地保留 30 天,约 400GB 磁盘,远端接 VictoriaMetrics 存 1 年(比 Thanos 省事,单机 binary 就能跑,维护成本低太多)
  • Alertmanager 三件套:group_wait 30s、group_interval 5m、repeat_interval 4h
  • inhibit_rules 做抑制:主机 down 的时候,抑制它上面所有的应用层告警,不然一次宕机会引起几十条连锁
  • 告警规则只留四类:延迟、错误率、饱和度(看 PSI 的 cpu.pressure 和 memory.pressure)、容量预测(predict_linear 4 小时推磁盘写满)

最关键的一条:所有 P2 级别只发企业微信,不打电话。我们内部有句话——「会打电话的告警,必须能指向一个用户可见的故障」。判断标准很土:如果用户没感觉,就不该吵醒人。

一个反方观点,以及我的回应

图片

有同事跟我说,你这套东西本质上是幸存者偏差,告警少了不等于问题少了。这话有道理,我也不打算假装自己没被这句话噎住过。所以我们现在每周五花 30 分钟做一件事:把上周所有 P0/P1 的告警拉出来,逐条问「如果这条没报,用户会不会发现」。答案是会,说明它有效;答案是不会,直接删规则。

删规则这事比加规则难十倍。加规则有成就感,删规则像在裸奔。但我的观察是,一个团队告警系统的健康度,跟规则数量是负相关的。你现在打开自己的 Alertmanager,rule 文件超过 500 行的,基本上都该做减法了。

最后说个我自己的翻车。2021 年我们用 Ansible 批量重启 Nginx,playbook 里忘了写 serial: 1,200 台机器同时 reload,负载均衡瞬间打满,P1 事故,MTTR 47 分钟。这个坑让我彻底明白:编排工具的默认行为,比它的功能更值得先读文档。

🏷️ 标签: