【背景】
做了 5 年运维,带过两个团队的值班,最直观的感受是:告警数量和业务故障数之间,从来没有正相关过。
去年接手一个新团队的时候,Prometheus + Alertmanager 里挂着 480 条告警规则。一个月下来,值班同学收到的告警里:
- 真正需要人动手处理的大约 60 条
- 剩下的 420 条,要么是同一根因的重复触发(GC 一抖,CPU / 内存 / 延迟三条一起响),要么是阈值定得太紧(磁盘 85% 就报,其实 95% 才有事),要么是早就该拆掉的历史遗留(一条规则挂了 3 年没人敢删)。
值班同学的口头禅从「这告警怎么又来了」变成「又来一波」。SRE 圈讲了很多年的「symptom-based alerting(基于症状告警)」,落到很多团队,其实还是「CPU > 80%」「内存 > 80%」「QPS 跌 30%」这种资源级、指标级的关键字报警。
【常见的几种做法,分歧点在哪】
我见过团队大致分三类:
- 资源派:告警规则跟着资源走。CPU、内存、磁盘、连接数、线程池、GC 次数,能采的都采,能报的都报。优点是「什么都能看见」,缺点是告警噪音大、根因靠人脑拼。
- 症状派:只报用户可感知的指标。错误率、P99 延迟、可用性、SLO 燃尽速度,其他一律不报。优点是值班聚焦,缺点是「看不见」不等于「不存在」,有些资源问题(比如磁盘 IO 打满)在症状上会延迟 10~30 分钟才暴露,窗口期内已经伤了用户。
- 混合派:核心链路用症状(SLO + 错误率 + P99),底层资源保留 3~5 条「兜底告警」(磁盘、OOM、进程退出),其余全部关掉。
分歧点基本落在两个问题上:
- 症状告警的阈值怎么定? 错误率 1% 还是 5%?P99 是绝对值(200ms)还是相对 SLO 的燃尽速度(1 小时内烧掉 10% 预算)?
- 资源告警到底留几条? 全删怕漏,留多了又是噪音,这个度谁都不敢先砍。
【我的倾向和理由】
我倾向「混合派」,具体做法是:
- 第一层(症状):每个核心服务 3 条——错误率、P99 延迟、SLO 燃尽速度。这三条响了,值班必须介入,不管是不是值班时间。
- 第二层(资源兜底):磁盘使用率 > 92%、进程退出、OOM、证书 < 7 天。这四条是「不报一定会出事」的,阈值定得比较宽,宁可少报几次也不误报。
- 其余全部关掉,包括 CPU / 内存 / 连接数 / GC 次数。
砍完之后,告警数从 480 降到 97 条,一个月真正需要人处理的从 60 条降到 41 条(没降太多,因为砍掉的 420 条里确实混着 19 条有价值的——这是代价,后面说)。
关键不是「砍掉多少」,而是每条留下的告警,都能回答「响了之后第一步做什么」。回答不了这个问题的告警,就该删。
【补一段:那 19 条「砍掉后才发现有价值」的告警,代价到底在哪】
原文说砍掉的 420 条里混着 19 条有价值的,具体拆开是这样的(都是我们复盘时一条条找回来的):
- GC pause > 1s 且同一 JVM 1 分钟内 3 次(19 条里占 7 条)。症状层看,这类问题在 P99 上往往只体现为「毛刺」——单次 200~500ms 的抖动,混在正常流量里被 P99 平滑掉了,燃尽速度都烧不到。教训:对延迟敏感的核心服务,把「单次 GC pause > 1s 且 1 分钟内 ≥3 次」保留为 P3(不上值班、只进看板),能提前 20~40 分钟看到 Full GC 前兆。
- 线程池 active 占比 > 80% 持续 60s(5 条)。这条我后来发现是「症状派」最容易漏的:连接池 / 线程池打满之前,错误率还是 0,P99 只是从 40ms 爬到 120ms,没破 200ms 的绝对阈值。教训:线程池/连接池的「active 占比」不是资源指标,它是「离打满还有多远」的领先信号,应该保留为 P3。
- 上游依赖 P99 相对自身 P99 的比值 > 3(4 条)。这条是我后来补的:自己服务的 P99 还在 SLO 内,但某个下游的 P99 已经比自己高 3 倍,说明问题在传导路上、还没打到自己。教训:跨服务的「相对延迟比」比绝对值更早暴露依赖劣化。
- 磁盘 IO wait > 30% 且 iops 突然掉 50%(3 条)。典型的「资源问题症状延迟 10~30 分钟才暴露」,砍掉这条后我们有一次 Redis 主从切换慢了 25 分钟才被发现,就是漏了这条。
这 19 条的共同点:它们不是「资源报警」,而是「资源问题的领先信号」——离症状爆发还有几分钟到几十分钟,窗口期内有操作空间。这是我和纯症状派最大的分歧:症状派把「资源」和「领先信号」混为一谈了,砍的时候一起砍掉,就漏了这 19 条。
【补一段:砍告警的决策清单(可直接抄)】
我后来把「这条告警该不该留」拆成一个 4 问清单,团队里每条告警都过一遍:
- 响了之后第一步做什么? 答不出来 = 删。这条是硬门槛,没有例外。
- 它比症状告警早多少? 早 < 5 分钟 = 删(窗口期太短,不如等症状);早 5~60 分钟 = 保留为 P3;早 > 60 分钟 = 可以保留为 P2。
- 过去 30 天它响过几次? 0 次 = 保留(可能是兜底);1~3 次 = 保留;> 5 次 = 必须重定阈值(要么太紧要么太松)。
- 它和哪条症状告警是同一根因? 如果和某条症状告警 100% 同源,且它不早于症状 5 分钟 = 删(重复报警)。
用这个清单过一遍,我们那 480 条一个月就从「砍到 97 条」变成「砍到 97 + 找回 19 = 116 条」——找回的 19 条比砍掉的 420 条更值钱,因为它们每一条都对应一次真实的「症状还没响、但已经能动手」的窗口。
【想听大家聊聊】
- 你们团队现在告警规则大概多少条?真正需要人处理的占多少?这个比例你们有统计过吗?
- 症状告警的阈值,你们是怎么定的?有没有踩过「阈值定太紧导致告警疲劳、太松导致漏报」的坑?具体数字可以说说。
- 资源告警你们留了几条?哪几条是「砍不得」的?
- 有没有团队试过把告警直接绑到 SLO 燃尽速度上?效果如何?
- 新增:你们有没有踩过「砍掉一条资源告警后,症状告警响了但已经晚了」的坑?具体是哪种资源信号、晚了多久?
我猜大家的故事会很有共鸣——毕竟「告警太多」这个痛点,每个值班过的团队都经历过。