告警机制原理:规则引擎、阈值设置、告警级别与分类
告警不是凭空蹦出来的。你想想看,日志从四面八方涌来,每秒几千条,人能看得过来吗?
所以我们需要一套自动化机制——规则引擎是大脑,阈值是尺子,告警级别是标签,分类是目录。这四个东西绑在一起,才构成一个靠谱的告警系统。
下面我把自己踩过的坑和总结的套路拆开讲。
规则引擎:脑回路怎么长的
规则引擎说白了就是一段条件逻辑——如果某事件发生,并且在某条件下,那就输出一个告警。我个人习惯先把规则拆成三块:
- 事件源:哪台设备、哪个服务、哪个进程的日志
- 匹配条件:关键词、正则、数值范围、出现次数
- 动作:生成告警、调用webhook、写入事件表
举个例子,一段简化的规则表达式(伪代码形式):
WHEN source = "web-server-01"
AND message MATCHES ".*500.*"
AND count_in_window(5min) > 3
THEN alert(
level = "critical",
title = "Web服务器连续500错误",
summary = "5分钟内出现{count}次500错误"
)
我在项目中遇到过一哥们把count_in_window的时间窗口设成10秒,结果上午11点业务高峰,5秒内就触发了阈值,整个监控屏炸成红色。这就是规则条件本身写得不够精细。
阈值设置:尺子不能歪
阈值定高了,漏洞漏到太平洋;阈值定低了,告警像鞭炮一样噼里啪啦。
我总结过一套叫基线+动态系数的方法:
- 静态基线:历史数据取P95或P99作为基础值。比如CPU过去7天的P95是65%,那就拿65%当基准。
- 动态系数:允许短期突发。比如阈值 = 基准 × 1.5,或者基准 + 3σ。
- 冷却机制:同一个源在N分钟内不重复告警,防止刷屏。
看下面的对比表格,不同阈值策略的优缺点一目了然:
| 策略 | 适用场景 | 缺点 |
|---|---|---|
| 固定值(如 CPU > 90%) | 资源接近上限的强故障 | 业务低谷期可能漏掉慢速爬升 |
| 同比/环比增长率 | 突增流量、刷票行为 | 需要历史数据,新服务没基线 |
| 动态百分位(如 P99 > 3σ) | 时序曲线不规则的服务 | 计算开销稍大 |
我记得有一次线上MySQL连接数突然从50跳到120,固定阈值没到150就没触发。但实际连接池已经用光了。后来改了动态百分位策略,就是上面表格第三行,才把这个坑填上。
告警级别:给异常贴标
级别不是越多越好。我个人经验:四档足够。多了反而容易混淆:
- Info:记录一下,不需要人盯。(比如“服务例行重启”)
- Warning:需要看一眼,但不用半夜起来。(比如“某接口P95延迟从200ms升到350ms”)
- Critical:立即处理,影响可用性。(比如“服务健康检查连续3次失败”)
- Emergency:全局瘫痪,需要拉作战群。(比如“整个Kubernetes集群失联”)
这里有个坑——很多团队把80%的告警都设成Critical,等于没有级别。你想想看,打开手机全是红色报警,人很快就麻木了。我习惯用“影响范围 + 是否自主恢复”两个维度来定级:
| 是否影响用户 | 能否自主恢复 | 建议级别 |
|---|---|---|
| 否 | 是(5分钟内自动恢复) | Info |
| 否 | 否 | Warning |
| 是 | 是(但延迟较长) | Warning → Critical 逐级升级 |
| 是 | 否 | Critical |
分类归纳:告警也要有家
一堆告警堆在那里,如果不分类,跟没告警差不多。我习惯按三层分类:
- 技术层次:基础设施、中间件、应用、安全
- 故障类型:资源耗尽、响应超时、错误率上升、连接失败
- 影响维度:单实例、部分可用、全局不可用
这样分类的好处是——应急响应时,你能秒级定位到“基础网络”还是“数据库”出了问题。我曾经在日志平台上跑过一个分类统计脚本,把过去一个月的告警按类聚一下,发现70%的Critical告警都集中在“数据库连接池耗尽”这一个子类上。后来直接加了个连接池自动扩容的脚本,这一类的告警直接降了80%。
下面这张图是我自己画的一个简化工作流,把上面四块串在一起,你看看就清楚了:
从上往下看,日志进来后先过规则引擎,符合条件的再拿阈值去比,通过后打个级别标签,最后归到对应分类。这个过程走完,一条有意义的告警才能进到你的工单系统或者OnCall通知里。
嗯,告警机制这部分就这些。下一条我们聊聊告警触发了之后,应急响应应该从哪儿下手——那是另一个话题了。