告警太多但诊断仍慢,问题常出在“没按故障链分层”
真正拖慢值班的,往往不是告警不够,而是 20 多条红点挤在同一层里。把告警按起点层、放大层、结果层重新整理,并绑定到第一轮动作上,团队才会从“看见很多异常”变成“顺着一条故障链往下收”。
有一次晚高峰,值班群里 6 分钟之内进了 23 条告警。
最刺眼的是网关 504。
第二刺眼的是订单接口超时。
再往下还有线程池队列、连接池 pending、数据库 RT、Redis 超时、消费堆积、命中率下降。
从“观测覆盖”这个角度看,这套监控很完整。可那天现场并没有因为告警齐全而更快,反而更慢。大家都在处理异常,但没有人敢说第一轮应该顺哪条线往下走。
事故后回放那 6 分钟时,我们发现真正有用的第一张图,根本不是告警墙,而是一条按时间摊开的变化顺序:
- 21:17,
promo-cache的超时和 miss 一起抬头。 - 21:18,
promotion-service连接池 pending 开始堆。 - 21:19,订单应用工作线程占满,重试量上升。
- 21:21,网关 504 和支付页超时全面冒头。
那次之后,团队才真正接受一件事:
告警多不等于诊断快。真正拖慢值班的,往往是所有告警都挤在一个平面上,看不出谁更接近起点,谁只是放大,谁只是最外层结果。
这篇文章不想再讲一套抽象的“告警治理原则”。我只想把那次事故逼出来的一条经验讲清:告警如果不按故障链分层,现场就只能追最红的那块屏。
我们当时不是缺告警,而是缺“先后感”
那天值班群里最常出现的三句话是:
- “504 先看吧,用户已经能感知了。”
- “数据库也红了,要不要先拉 DBA?”
- “Redis 也在抖,到底谁是起点?”
这三句话都不算错。
错的是它们都把同一条故障链上的信号,当成了并列问题。
如果你把下面这些东西同时摆平:
- 外层报错
- 中间资源堆积
- 最底层依赖波动
值班现场就会天然分裂成几拨人,各追各的红点。人越多,越容易形成一种错觉:大家都在干活,所以现场应该在收敛。其实只是把一条链拆成了几摊噪音。
后来复盘时最扎心的一句评价不是“告警漏了”,而是:
所有告警都对,但它们没有帮助值班同学判断先看哪一层。
后来我们怎么把同一批告警重新摆位置
事故结束后,我们没有先删告警,也没有先讨论阈值。
我们先做了一件很笨但很有用的事:把那次事故里所有触发过的告警按“它在故障链里所处的位置”重新贴墙。
贴完以后,才有了下面这三个层次。
第一层:起点层
这层不是“最严重”,而是最可能最早分叉。
在那次故障里,属于这一层的是:
promo-cache超时- cache miss 异常升高
- 热 key 回源数上升
它们未必最响,也未必第一时间有人感知,但最接近那块第一张倒下的牌。
第二层:放大层
这层信号说明故障已经不只停在起点,而是在系统里开始传导和放大。
那次对应的是:
promotion-service连接池 pending- 订单服务工作线程占满
- 同步重试次数上升
- 消费积压开始出现
这一层最有用的地方,是告诉你事故是否已经从“一个点慢”变成“整条链在自激”。
第三层:结果层
这层是用户最容易感知、业务最容易报警的部分。
例如:
- 网关 504
- 下单超时率升高
- 支付页白屏
- SLA 告警
这层当然重要,因为它决定影响范围和升级动作。但它通常不是第一轮最值得追的“根”。
分层不是给监控平台看的,是给值班动作看的
很多团队做告警分层,最后会做成一份监控平台里的标签体系。颜色变了、目录变了、owner 也写清楚了,但现场还是慢。
原因是它没有和动作绑在一起。
那次之后,我们给三层告警各自配了完全不同的第一反应。
起点层告警响了,先做证据对齐
不是立刻拉所有人,而是先确认:
- 影响的是哪条业务链。
- 是单实例、单机房,还是全量。
- 最近有没有变更、切流、回填、重试策略调整。
起点层的目标不是把事情说大,而是尽快把“哪条链在先坏”说清。
放大层告警响了,先判断要不要止血
如果放大层已经连续抬高,就别再把现场当成单点故障慢慢看。
这时更重要的是:
- 重试要不要先关。
- 批任务要不要暂停。
- 非核心入口要不要限流。
- 哪些动作低风险、可逆,而且能直接减压。
放大层不负责解释根因,它负责告诉你:再不动,系统会不会自己把自己拖穿。
结果层告警响了,先判断影响面和升级面
结果层不是没用,而是职责不同。
它更适合回答:
- 这事影响多少用户。
- 是不是需要业务方同步。
- 是否需要升级响应级别。
- 哪条核心链路必须优先保住。
如果把结果层拿来当第一定位入口,现场很容易一直盯着最外层症状打转。
这套分层不是在会议室里想出来的,是被第二次事故验证出来的
第一次事故后,大家其实还是半信半疑。
真正让这套分层站住脚的是两周后的一次相似事故。
那次也是告警一片红,但值班同学没有再从网关 504 开始。他先看起点层面板,发现最早抬头的是 inventory-cache 回源数和 Redis 慢命令;再看放大层,发现重试数和线程池 queue 还没完全起势;于是先把现场判断成“起点已出现,但还没进入全面放大”,没有一上来就做大动作。
结果是:
- 5 分钟内就把主线收到了缓存层。
- 没有因为最外层 504 把人全都拉去看网关。
- 也没有因为数据库 RT 随后抬头,就把数据库当成先坏的那一层。
这时候团队才真正意识到,所谓“告警分层”并不是治理口号,而是值班现场在跟时间赛跑时,必须先拿到的一种顺序感。
真正该删掉的,不一定是噪音最多的,而是“没有收敛价值”的
告警重排之后,我们顺手删掉了一批以前觉得不能动的告警。
删的标准很简单:
- 它是否帮助第一轮判断起点。
- 它是否帮助判断事故是否已进入放大。
- 它是否帮助判断用户影响和升级面。
如果一条告警满足不了这三类中的任何一种,只是在故障时固定跟着别的信号一起响,那它大概率就是“看着重要,现场没用”。
比如有些 JVM 次级指标,平时看很细,真出事时却只会在结果层统一变红。它不是不能留,而是不该继续站在值班主视图最前面。
这件事的边界也很清楚
如果你现在还处在“多个告警同时响,但连影响面都没切出来”的阶段,先去做第一轮范围切分,比重排告警更重要。像值班时看到多个告警同时响,第一轮该怎样做范围切分?这种问题,优先级比治理动作高。
如果你已经明确卡在某条慢链、超时风暴或回滚动作上,也别在这里兜。那已经不是“告警怎么分层”,而是要沿具体链路继续往下查。
这篇只处理一种场景:你们的告警并不少,但它们没有把值班现场收成一条故障链。
我后来最看重的,不是分了几层,而是值班群里的第一句话变了
以前事故刚开始时,群里第一句话通常是:
- “谁看一下 504?”
- “数据库是不是有问题?”
- “怎么这么多告警?”
后来慢慢变成:
- “最早抬头的是哪一层?”
- “放大器起来没有?”
- “外层结果已经影响到哪些用户?”
这不是措辞变化,而是值班习惯真的换了方向。
如果一套告警体系做完以后,现场第一句话还是“最红的是哪块”,那它再完整,也只是更大的告警墙。
真正有用的分层,应该让人更快找到第一张倒下的牌,也更快看清哪几张已经开始一起倒了。