4. 告警收敛策略:基于规则的收敛、基于时间窗口的收敛、基于拓扑的收敛

告警风暴,说白了就是监控系统在“发疯”。

我记得刚带团队那会儿,有一次核心数据库切换,结果监控系统瞬间喷出两万多条告警。整个值班群直接炸锅,真正有用的那条“主库宕机”反而被淹没了。从那天起,我就铁了心要把告警收敛做好。

今天聊的这三种收敛策略,是我这些年用得最多的三板斧。它们各有各的脾气,也各有各的适用场景。

4.1 基于规则的收敛:最直接,也最容易踩坑

基于规则的收敛,说白了就是“如果A发生,就别报B”。

举个例子:

  • 如果“磁盘使用率 > 90%”已经告警,那么“磁盘使用率 > 80%”的告警自动屏蔽
  • 如果“服务进程挂了”,那么“健康检查失败”的告警就不需要重复报

我在项目中遇到过最典型的场景:某次上线后,一台机器的CPU持续100%。结果监控系统同时报了“CPU高”、“响应超时”、“连接数满”、“错误率飙升”四条告警。其实根源就一个——CPU被打满了。

核心原则:基于规则的收敛,本质是建立告警之间的“父子关系”或“抑制关系”。

实现方式其实不复杂:

# 伪代码示例:规则引擎判断逻辑
def should_suppress(new_alert, active_alerts):
    for rule in suppression_rules:
        if rule.match(new_alert) and rule.has_parent(active_alerts):
            return True  # 这条告警被抑制
    return False

我曾经踩过的坑:规则写得太死。比如“如果CPU高,就抑制所有其他告警”。结果有一次CPU确实高了,但同时也发生了内存泄漏,结果内存泄漏的告警被抑制了,问题排查多花了两个小时。

所以,规则收敛一定要留“白名单”通道。有些告警,即使有父告警存在,也必须报出来。

4.2 基于时间窗口的收敛:治“反复报”的良药

你有没有遇到过这种情况?

一个服务每隔5分钟抖动一下,每次抖动持续30秒。监控系统每5分钟报一次警,一天下来能报288次。值班同学看到最后直接麻木了——“哦,又是那个服务在抽风”。

这就是典型的“告警疲劳”。

基于时间窗口的收敛,就是解决这个问题的。

核心思路:

  • 聚合窗口:设定一个时间窗口(比如5分钟),窗口内相同类型的告警只发一条
  • 静默期:告警发出后,设定一个静默期(比如30分钟),期间不再重复告警
  • 升级机制:如果告警持续超过N个窗口,升级告警级别
窗口类型 典型时长 适用场景
聚合窗口 1-5分钟 网络抖动、服务短暂不可用
静默期 30-60分钟 已知问题的重复告警
升级窗口 3-6个窗口 持续未恢复的严重问题

我个人的习惯:时间窗口不要设得太长。我曾经图省事,把聚合窗口设成了30分钟。结果有一次服务真的挂了,但因为是窗口期内,告警被聚合了,等窗口结束才发出第一条告警——晚了整整半小时。

嗯,从那以后,我的聚合窗口就没超过5分钟。

4.3 基于拓扑的收敛:从“点”到“面”的降维打击

这是三种策略里最有技术含量的一种,也是我个人最喜欢的。

你想想看,一个电商系统,用户下单报错了。可能的原因有哪些?

  • 前端网关挂了
  • 订单服务挂了
  • 数据库挂了
  • 网络不通了

如果这些组件各自独立告警,那一次故障能报出几十条。但如果你知道它们的依赖关系——前端网关依赖订单服务,订单服务依赖数据库——那事情就简单了。

基于拓扑的收敛,就是利用系统的依赖关系,只报“根因”告警。

实现思路:

  1. 构建服务依赖拓扑图(谁依赖谁)
  2. 当多个告警同时发生时,从拓扑的“下游”往“上游”追溯
  3. 找到最上游的故障点,只报那一条告警
  4. 下游的告警自动标记为“衍生告警”

举个例子:

数据库宕机 → 订单服务超时 → API网关报错 → 用户看到“系统繁忙”

拓扑收敛后,只报一条:“数据库宕机(根因)”。其他三条自动归为衍生告警,不推送。

这里我画了一张图,帮你理解这三种收敛策略的关系:

告警收敛三大策略 原始告警流(风暴) 规则收敛 时间窗口收敛 拓扑收敛 收敛后告警 原始告警:100条/分钟 收敛后:3-5条/分钟 三种策略的适用场景对比 ● 规则收敛: 告警之间有明确的因果关系(如:进程挂→健康检查失败) ● 时间窗口收敛: 告警频繁但短暂(如:网络抖动、服务闪断) ● 拓扑收敛: 服务有明确的依赖关系(如:微服务架构、数据库→应用→网关)

这里要特别提醒:拓扑收敛依赖准确的依赖关系。我见过不少团队,拓扑图画得漂漂亮亮,但实际运行时依赖关系早就变了。结果拓扑收敛反而把真正的根因给收敛掉了。

所以,拓扑关系一定要动态维护。我建议每24小时自动刷新一次,或者通过调用链数据自动生成。

4.4 三种策略怎么选?

说实话,没有银弹。

我个人的经验是:

  • 小团队、系统简单:先用规则收敛,成本最低,见效最快
  • 系统有周期性抖动:加上时间窗口收敛,能过滤掉大量无效告警
  • 微服务架构、依赖复杂:拓扑收敛是必须的,否则根本看不清楚根因

但最理想的状态,是三种策略配合使用。规则收敛做第一道过滤,时间窗口做第二道去重,拓扑收敛做最后的根因定位。三层过滤下来,告警量至少能降80%。

最后分享一个我的小习惯:每次上线新策略,我都会先跑一周的“观察模式”——只标记哪些告警会被收敛,但不真正屏蔽。一周后复盘,看看有没有误杀。确认没问题了,再正式启用。

嗯,稳一点,总没错。


公众号:蓝海资料掘金营,微信deep3321