告警为什么总在你刚睡着的时候响?
这可能不是玄学,而是你的告警系统设计逻辑出了根本性问题。上周我处理了一个客户的案例:他们一个K8s集群的告警每天深夜2-4点集中爆发,值班人员连续一周睡眠不足,但业务侧的数据显示这期间根本没有用户请求高峰。查到最后发现,是他们的cronjob在凌晨统一跑日志清理,导致的CPU瞬时飙升触发了一个15%阈值的告警——而这个告警在设计时根本没人想到要结合业务流量周期去配置。
这是大多数监控告警系统的通病:用静态的视角看动态的系统,用机器的逻辑定义人的体验。我见过太多团队在配置告警时,只关注"这个指标异常了要通知我",却很少问"这个通知对业务恢复有什么实际帮助"。这个问题不解决,你和告警噪音的关系会一直处于被动的猫鼠游戏里。
传统告警哲学的三大陷阱
第一,盲目追求全面监控。有团队在Grafana上拉了200+个面板,每个面板配了3-5条告警规则,结果告警列表永远刷不完。这个坑的根源是把"监控"等同于"告警"——其实90%的监控数据根本不需要实时告警,它们只需要在问题排查时被查询就够了。告警应该是一个减约系统,而不是一个记录系统。
第二,静态阈值的自欺欺人。比如给API延迟配"超过300ms告警",看起来合理对吧?但真实的用户访问是波动的,白天通勤时间的移动网络延迟和凌晨公司内网延迟怎么可能是同一个基准?我们给某个银行客户做压测时发现,他们的核心交易接口在日间高峰P99延迟为480ms,凌晨低峰时P99只有220ms。如果你在300ms设卡,白天告警刷屏,凌晨则风平浪静——你永远在错误的时间接到错误的信息。
第三,把告警当任务分配工具。很多团队的做法是:告警触发→创建工单→指派给后端组。听起来流程完备,但仔细看数据:那个银行客户一个季度里产生告警工单1427张,其中真正导致用户可见故障的只有38张,占比2.7%。剩下97.3%的告警只是技术指标波动,根本不需要人介入。更糟糕的是,因为告警太频繁,核心成员开始养成"先忽略,等二次通知再处理"的习惯——真正的事故发生时,响应速度反而慢了。
换个视角:告警应该反映业务价值
我最近和一个做了8年SRE的朋友聊,他说自己的团队终于把告警量降到了原来的30%,但业务满意度反而提高了。核心变化是:他们把告警从"技术指标异常"重定义为"业务承诺(SLO)存在风险"。
具体怎么做的?举一个最简单的例子:一件商品下单接口的P95延迟。传统做法是:P95超过500ms就告警。他们的做法是:先算出这个接口的SLO是"每月99.9%的请求在800ms内完成",然后通过过去3个月的流量和性能数据反推,800ms对应的实时P95大概在什么水位——通常是620ms左右徘徊。于是他们设置了一个分层告警:当P95突破1000ms时触发P1(严重),因为这意味着该小时SLO大概率会被打破;突破800ms触发P2,需要确认是否有降级风险;低于800ms但突增50%以上触发P3,记录观察。
这样设计之后,深夜告警从之前的每天平均11.8次降到每周1.4次,而真正的故障一次都没漏掉——因为他们把注意力从"指标本身"转移到了"业务承诺的达成概率"上。用户不管你的CPU是不是飙到了90%,用户只关心下单或支付能不能成功。所以你的告警规则也应该围绕"用户的体验是否会受影响"来设计,而不是围绕"服务器的哪些硬件参数不够理想"。
另外,告警内容里的信息密度也值得推敲。很多告警消息只有一行"CPU 87%",没有上下文,值班的人还要花3-5分钟去翻Grafana找环比、找调用链——这完全是把排查成本转嫁给受害者。一个有效的告警消息至少应该包含:当前指标值、最近15分钟的走势、相关联的业务接口或主机IP、对应的SLO余量或预估影响范围。有些团队用Webhook把告警推送到IM后基于这些上下文自动生成一张排障指引卡片,这种思路的变体确实比传统的通知机器人有用得多。
一次告警治理的完整落地路径
如果你决定开始做告警治理,这里有一个可参考的步骤,是按我们实际服务客户时梳理出来的:
-
盘点现有告警规则。把所有Prometheus/Zabbix/云监控里的规则导出成表格,列出指标名、阈值、触发次数、对应的人。你大概率会发现超过50%的告警规则在过去30天里一次都没触发过——它们只是遗产。
-
给告警分业务等级。每个告警规则必须关联一个业务模块和用户路径。比如"支付服务错误率"关联的是"支付链路","Redis内存"关联的是"用户登录会话存储"。无关业务影响的告警一律降级为日志记录或仪表盘展示,不进入通知渠道。
-
用动态阈值替代静态阈值。有两种方式:简单的方式是取最近7天同时段的指标均值,设定基线上下浮动50%为告警阈值;复杂的方式用内置机器学习模型(比如Prometheus的predict_linear函数或云厂商的智能告警),预测未来30分钟的趋势值,如果趋势值超过某个绝对值才告警。直观感受是,动态阈值的有效告警率至少比静态阈值高35%-50%。
-
告警合并与去重。同一个事件在多个指标上都有表现时,只发一条综合告警。比如"订单模块大量超时"和"订单容器CPU超90%"可能是一个问题的两面,合并成一条"订单模块可能异常,错误率P95 2.3%,关联容器CPU超90%"比分别发两条效果更好。
-
每次事故后做告警回放。发生线上问题时,把监控数据和告警记录拿出来过一遍:这条告警的时间点是否早于用户投诉?如果是,为什么没有引起重视?如果不是,需要补一条什么规则才能提前半小时以上发现?这个循环持续做三个复盘周期,你的告警命中率会有质的提升。
你需要容忍一定的"盲区"
最后想说的是:告警系统不是越灵敏越好。有一个反直觉的事实——我们之前对比过几个团队的告警配置和响应效率,发现告警规则数和MTTR(平均恢复时间)呈U型关系:规则太多,MTTR变长(因为大量噪音麻痹了响应者);规则太少,MTTR也变长(因为发现问题时往往已经扩散)。最优点出现在告警规则数控制在每人负责的指标不超过15个左右,并且每天的睡眠告警(不需要人处理的)低于3条的时候。
我记得有个客户非常极致地追求告警覆盖率,为每一个容器都设置了内存告警,结果一周后运营和运维都疲了,真正核心的数据库主从切换告警反而被淹没在成群的通知里。所以不妨跟你自己的系统说一声:允许它有一些小毛病,只要这些毛病不会直接影响用户,让它们冷静地待在监控面板上就好。这比严防死守更健康。
如果你现在正被告警疲劳折磨,我的建议是从明天开始的第一步不是调阈值,而是把指标分类为"强告警"和"弱监控"两类。强告警只保留与SLO直接挂钩的核心指标,弱监控全部踢出通知渠道。你会经历一段适应期,会有那么一两次"哎呀这个指标忘了通知"的惊讶体验,但只要挺过去,整体的响应效率和系统的真实稳定性反而会往更好的方向走。监控告警的价值从来不是"最全",而是"恰好"。