一条数据库抖动触发 300 条告警,值班人第一反应是先静音再排查。本文讲炬鲸 OBSERVE 用分组、抑制、静默三种手段做告警收敛,附 YAML 配置示例与排班升级建议。
凌晨两点,核心数据库出现 30 秒慢查询。这 30 秒里发生了一连串连锁反应:慢查询触发数据库监控告警,依赖它的订单服务开始超时报错,网关层错误率随之飙升,链路追踪里大量 span 延迟集体超标。等值班同学打开手机,已经收到 300 多条告警,分别来自 5 个不同的系统——短信、邮件、IM 群同时刷屏。而真正的问题只有一个——数据库抖动——但没人能在 300 条里一眼看出来。值班人前十分钟不是在排查,而是在关静音。
告警的价值是"告诉你哪里坏了",而不是"告诉你坏了很多次"。一条业务故障触发几十条告警时,第一反应不是排查,而是先静音。这就是告警疲劳,也是告警系统最常见的失败方式:一个吵个不停的系统,最终不是被调优,而是被无视,等真出大事故时它已经没人信了。
炬鲸 OBSERVE 的告警引擎在"触发之后、送达之前"做三道处理,顺序是固定的:先分组、再抑制、最后让静默兜底。
分组(Grouping):把同一规则下标签相近的告警合并成一条。比如按 service 和 host 分组,同一台机器上的 10 条"CPU 使用率超阈值"合并成一条,通知里附上这 10 条的时间线,而不是刷 10 条消息,把真正关键的那条淹没。
抑制(Inhibition):定义告警之间的依赖关系。数据库宕机必然导致下游服务连接失败,配置"数据库宕机告警 → 抑制下游连接失败告警"后,下游这些告警不再单独送达,等数据库恢复后自动解除。抑制正是把"一次抖动变成 300 条告警"从根上打断的那道工序。
静默(Silence):发版、维护、压测这些计划内操作,提前挂静默,让预期内的告警根本不要到达任何人。
在控制台「告警规则」页,一条抑制规则长这样:
inhibit:
- source: "db_mysql_down"
target: "service_connection_failed"
equal: ["env", "cluster"]
equal 限制了抑制范围:只有当环境和集群一致时才抑制,避免误伤其他环境里真实发生的同类告警。分组规则同样直接:
group_by: ["service", "host"]
group_wait: 10s
group_interval: 5m
group_wait 是合并窗口,10 秒内到达的同组告警合并成一条;group_interval 控制后续新告警如何追加到同一条通知,而不是另起一条。两者配合,把"每个失败项一条告警"变成"每次事故一条告警"。
收敛解决"告警太多",排班解决"谁来响应"。把轮值表配上升级规则:P0 告警 10 分钟未确认,自动电话通知二线负责人,30 分钟仍未确认就上报经理。三件事串起来——先收敛、再送达、后升级——值班才能真正扛住,而不是被耗干。
留一条最简单的原则:告警系统不应该比故障本身更吵。先把噪声压下去,再谈智能分析。大多数抱怨"告警太多"的团队,缺的不是更聪明的告警系统,而是把这三道处理套到已有的那套上。