一次服务抖动就能触发几十条重复告警,值班手机被打爆。本文拆解炬鲸 OBSERVE 告警引擎的聚合、抑制、静默与值班升级四个机制,并给出可直接复用的配置示例和衡量标准。
一次服务抖动,几十台实例同时报错,每条错误各触发一条告警,值班手机连响十分钟。等真正翻到那条关键的 OOM 告警时,事故已经扩大了。更常见的是另一种结局:因为平时告警太多太杂,值班员早就把通知设成了静音,真正需要人介入的故障反而被淹没在噪声里。告警的价值从来不在数量,而在"该响的响、不该响的别响"——做不到这一点,告警就从保障变成噪声,系统也就形同虚设。所以治理告警,第一步不是加更多规则,而是先把已经存在的噪声压下去。
炬鲸 OBSERVE 的告警引擎支持按维度聚合。下面这条规则,让同一 service、同一 cluster 的错误率告警在 30 秒窗口内只通知一次:
alert:
name: service-error-rate
expr: error_rate{service="order-service"} > 5
for: 1m
group_by: [service, cluster]
group_wait: 30s
group_interval: 5m
通知里会带上"已聚合 42 条",点开才是明细。三个参数各管一段:for 是防抖,短暂抖动能自愈就不打扰人;group_wait 把同一波到达的告警攒在一起再发第一条;group_interval 控制聚合后的重复提醒频率,避免同一批告警每隔一分钟骚扰一次。
聚合最关键的是选对维度:太粗会把无关告警搅在一起,太细等于没聚合。一般用 service + cluster 起步,再按环境、机房细分。一个反例是拿 trace_id 当维度——每条链路都不同,等于把聚合废掉了。
两个容易被忽略的手段。
一是抑制(inhibition):数据库连接池耗尽时,下游几百个"连接超时"会同时炸出来。配置一条抑制规则,让"数据库不可用"压住"连接超时",值班员一眼看到根因,而不是满屏表象:
inhibit:
source: db_unavailable
target: downstream_connection_timeout
equal: [service]
equal 限制了生效范围:只有源和目标共享相同标签值时才抑制,避免 A 集群的数据库故障把 B 集群真实的连接问题也盖住。抑制可以级联,比如"机房断网"压"数据库不可用"再压"连接超时",层层收敛到最后只剩一条根因。
二是静默(silence):计划内的发布、压测、机房割接,提前把相关告警静默一段时间,避免误报消耗注意力。静默必须设到期时间,否则忘了关,真故障就会在静默中悄悄过去。常见做法是把静默窗口和发布窗口绑在一起:凌晨 2 点到 3 点静默"服务重启"告警,3 点一过自动恢复常规阈值。
在聚合之前,先给每条规则定一个 severity:P1 是核心链路受损、需要立即处理;P2 是局部异常、半小时内处理;P3 是隐患、今天处理即可。分级决定了两件事:通知走哪个通道,以及要不要半夜把人叫醒。
告警最终要落到人。炬鲸 OBSERVE 内置排班表:按周轮换,主备双人,支持临时换班;通知走企微、邮件、短信多通道,低级别告警可配免打扰时段,凌晨 3 点的 P3 等到早上再响。升级链默认三段——先通知一线,5 分钟未确认自动升级二线,再过 10 分钟电话兜底。每次通知和确认都有留痕,事后复盘能还原"谁在几点看到、几点处理、在哪一步交接卡住了"。
最后给一条可落地的判断标准:每周统计三个数——误报率(开了通知却没人需要处理的占比)、平均确认时间(MTTA)、平均恢复时间(MTTR)。误报率长期高于 20%,说明阈值或规则有问题,该改规则而不是再加人。新告警规则先跑一周"静默观察"模式,只记录不通知,确认误报率可接受再开启通知。告警系统最大的敌人不是漏报,而是把人都训成"狼来了"。