两种告警降噪的思路
在监控领域,告警风暴是一个很常见且痛苦的问题。如果故障复盘时发现缺少对应的告警,那运维人员就会被批评,运维人员被批评的多了,就会把各种告警都配上,最终导致告警事件增多,形成告警风暴,进而,一些重要的告警又被淹没,也导致疏漏,真是痛苦不堪。
如何解决告警风暴问题?通常有两个办法:
- 源头上治理告警规则。这个在之前的专栏里有介绍,这里不再赘述。
- 技术工具做告警降噪。即:把众多告警事件做收敛,聚合成一个一个的告警事件集(通常称为 incident),然后再对 incident 做告警,可以大幅减少告警通知的数量,便于运维人员快速了解故障的全貌。
本文会介绍技术层面两种告警降噪的实现思路,供大家选型参考。
基于时间窗口的告警降噪
这种方式较为直观,即:在一个时间窗口内,把相同类别的告警事件聚合成一个 incident,然后再对 incident 做告警。比如张三在最近 5 分钟内收到 3 条原始告警事件:
告警事件1:
- alertname: CPU 使用率超过 90%
- instance: 10.1.2.3
- severity: Warning
告警事件2:
- alertname: CPU 使用率超过 90%
- instance: 10.1.2.4
- severity: Warning
告警事件3:
- alertname: CPU 使用率超过 90%
- instance: 10.1.2.5
- severity: Warning
这三条告警事件的 alertname、severity 都是相同的,只有 instance 不同,那么我们可以把这三条告警事件聚合成一个 incident。但是这三条事件并非同一时刻产生,所以我们需要一个时间窗口,比如 5 分钟,只有在 5 分钟内产生的告警事件才能聚合成一个 incident。
这样的好处是,确实做到了同类事件的聚合通知,减少的通知次数。坏处是不够实时,因为需要等待时间窗口结束才能做告警。
更进一步,我们可以稍作优化。不同的级别不同的窗口,比如:
- Info 级别的告警,不太重要,聚合时间窗口可以设置大一些,比如 15 分钟;
- Warning 级别的告警,相对重要,聚合时间窗口可以设置小一些,比如 5 分钟;
- Critical 级别的告警,非常重要,聚合时间窗口可以设置更小一些,比如 1 分钟甚至 10 秒钟。
看起来是不是更合理了?的确。但是还是不完美,问题在:
- 实时性是硬伤,因为需要等待时间窗口结束才能做告警;虽然区分级别对待了,只是缓解无法根治。
- 窗口是硬性的,稍微超过窗口时间,就会导致告警事件被分开,产生多条通知。
有没有其他思路?
Flashduty 基于滑动窗口合并,且实时通知
Flashduty 也是允许用户配置一个时间窗口,不过是滑动窗口,而不是硬性窗口。比如我们配置一个 5 分钟的滑动窗口,在窗口结束的一刻,恰好来了一条告警事件,那这个窗口就会继续延展 5 分钟,直到 5 分钟内没有告警事件产生,窗口才会关闭。
如果等窗口关闭才触发通知,那实时性就太差了。Flashduty 的做法是只要生成了 incident 就会立马通知(或按照用户的配置,等待一会再通知,默认是立马通知),先让用户知道有 incident 产生了,然后新的告警事件进来,会继续合并到这个 incident 里,不再继续通知。
只要生成了 incident 就立马通知,通知的内容里没有办法聚合很多事件,这算是一个小问题。不过相比通知即时性,两相权衡取其轻,我们认为是值得的。另外,如果是飞书卡片、钉钉卡片等通知方式,Flashduty 会在后续新事件进来时,自动更新卡片内容,这样用户就能看到最新的合并结果了。
比如上面的告警通知卡片,显示的聚合告警 3 条,如果后续有新的告警事件进来,会自动更新卡片上的数字,可能变成 4 条、5 条等。
另外,Flashduty 不但支持常规的标签规则聚合,还支持智能聚合,减少配置成本:
另外在聚合的时候,可以支持层级规则聚合,默认走默认聚合规则,有些告警事件如果想走特殊规则,也可以做到:
结语
告警风暴是一个很让人头疼的问题。而且,一个公司通常会部署多套监控系统(云上的、云下的),监控系统自身侧重点是数据采集、存储、展示、告警事件生成,对于告警事件生成之后的收敛降噪、排班认领升级协同等,往往不太重视。这时候,PagerDuty、Flashduty 等 OnCall 类产品就可以发挥作用了,它们可以把各类告警事件接到一个中心,统一做降噪、分发、分析等,加速故障响应。Flashduty 的产品介绍和注册体验可以参考 👇