告警分级 = 系统的反馈调节策略
解决什么问题:如何在系统异常时给出恰当的反馈信号—— 既不能太迟钝(事故扩大),也不能太敏感(告警疲劳、误报)。
业务问题
真实场景
场景 1:告警风暴
半夜 3 点收到 1000 条告警,全是磁盘空间 80% 警告
- SRE 工程师疲于应付
- 真正的事故(P0)淹没在告警噪声里
- 等工程师看到 P0 时已经晚了场景 2:告警失灵
某天 P99 延迟飙到 5s,业务方投诉
但监控只对"完全宕机"告警,没有针对性能下降的告警
→ 监控系统"活着",但已经失灵场景 3:告警误报
凌晨数据库抖动(持续 30 秒),触发 P0 告警
SRE 立刻响应,结果只是个临时抖动
→ 每次告警都"狼来了"
→ 真正 P0 时,团队已经麻木失败的典型做法
做法 1:所有异常都告警
✗ CPU > 80% 告警
✗ 内存 > 80% 告警
✗ 磁盘 > 80% 告警
✗ QPS > 1000 告警
✗ 错误率 > 0.1% 告警
...
后果:告警疲劳,真正的事故无人响应做法 2:只有完全宕机才告警
✗ HTTP 5xx > 50% 才告警
✗ 服务完全不可用才告警
后果:性能下降无人知晓,用户已经流失做法 3:固定阈值告警
✗ "CPU > 90%" 告警(不考虑业务时间)
后果:业务低峰时的 CPU 90% 可能是正常的
业务高峰时的 CPU 70% 已经是问题控制论视角
数学原型
钱学森《工程控制论》Ch 7 §7.5: "非线性系统的响应分为软激发和硬激发两种—— 软激发:响应与输入成连续函数关系(线性/指数) 硬激发:响应在阈值处发生突变(继电器、限幅器)"
钱学森 §7.5: "当系统处于自激振荡状态时,振动的振幅由系统的非线性特性决定, 而与初始条件的精确值无关。"
钱学森 §7.5: "频率侵占与滞回——为了避免系统在阈值附近频繁切换, 设计两个不同的进入/退出阈值(滞回)。"
控制论解法
告警分级 = 软激发 + 硬激发的组合 + 滞回设计:
软激发:渐进告警(如性能下降趋势)
硬激发:紧急告警(如完全宕机)
滞回:进入告警阈值 > 退出告警阈值(避免频繁切换)与业务的对应
| 控制论概念 | 软件工程 |
|---|---|
| 软激发 | 渐进告警(性能下降趋势) |
| 硬激发 | 紧急告警(完全宕机) |
| 滞回(Hysteresis) | 进入阈值 > 退出阈值 |
| 频率侵占 | 阈值附近的频繁切换 |
| 自激振荡 | 告警疲劳 |
核心概念
定义
告警分级:根据异常的严重程度、紧急程度、业务影响范围,将告警分为不同等级,并匹配不同的响应策略。
四级告警体系
┌────────┬─────────────────┬────────────────────────┐
│ 级别 │ 触发条件 │ 响应策略 │
├────────┼─────────────────┼────────────────────────┤
│ P0 │ 完全不可用 │ 立即响应,5 分钟内介入 │
│ P1 │ 性能严重下降 │ 15 分钟内响应,业务受损 │
│ P2 │ 性能轻微下降 │ 1 小时内响应,潜在风险 │
│ P3 │ 资源预警 │ 24 小时内处理,预防性 │
└────────┴─────────────────┴────────────────────────┘关键属性
| 属性 | 含义 |
|---|---|
| 分级明确 | 每级有清晰的触发条件和响应策略 |
| 软硬搭配 | P0 硬激发(紧急),P2/P3 软激发(渐进) |
| 滞回设计 | 进入告警的阈值 > 退出告警的阈值 |
| 告警聚合 | 同一根因的多条告警聚合成一条 |
| 值班轮换 | 不同级别匹配不同的值班响应 |
软硬激发对照
软激发(渐进响应):
- 输入缓慢变化 → 输出缓慢变化
- 例:CPU 从 50% 慢慢涨到 80%
- 响应:渐进告警 → 自动调节(限流、扩容)
硬激发(突变响应):
- 输入超过阈值 → 输出突变
- 例:服务完全宕机、数据库连接失败
- 响应:紧急告警 → 立即人工介入滞回设计
告警进入阈值:CPU > 90%
告警退出阈值:CPU < 70%
(差值 = 滞回带 = 20%)
→ 避免 CPU 在 85% 附近频繁进出告警状态工程实践
步骤 1:定义告警分级标准
P0(紧急 / 硬激发):
- 触发:服务完全不可用 / 核心业务完全中断
- 例子:
- HTTP 5xx > 50% 持续 1 分钟
- 数据库主从全部宕机
- 支付服务不可用
- 响应:5 分钟内介入,值班工程师 + 主管
P1(严重 / 硬激发):
- 触发:性能严重下降 / 部分业务受损
- 例子:
- P99 延迟 > SLO 2 倍
- 错误率 > 5%
- 核心业务部分功能不可用
- 响应:15 分钟内响应,值班工程师
P2(警告 / 软激发):
- 触发:性能轻微下降 / 潜在风险
- 例子:
- P99 延迟超过 SLO 但 < 2 倍 SLO
- 错误率 0.5%-5%
- 资源使用率 > 80% 持续 10 分钟
- 响应:1 小时内响应,工单跟进
P3(提醒 / 软激发):
- 触发:资源预警 / 容量规划信号
- 例子:
- 资源使用率 > 70% 持续 1 小时
- 数据库慢查询增多
- 业务异常趋势
- 响应:24 小时内处理,工单池步骤 2:每个告警加滞回设计
┌────────────────────────────┬────────────────┐
│ 告警 │ 阈值对 │
├────────────────────────────┼────────────────┤
│ CPU 使用率 │ 进 90% / 出 70% │
│ 内存使用率 │ 进 90% / 出 75% │
│ 数据库连接池 │ 进 85% / 出 70% │
│ 消息队列堆积 │ 进 1000 / 出 100 │
│ P99 延迟 │ 进 2x SLO / 出 1.2x SLO │
│ 错误率 │ 进 5% / 出 1% │
└────────────────────────────┴────────────────┘步骤 3:告警聚合(避免告警风暴)
同一根因的多条告警要聚合:
例:
- 数据库慢查询 → 触发 5 条告警(CPU、内存、连接池、慢查询、应用超时)
- 聚合为 1 条:"数据库性能下降,包含 5 个指标异常"
实现:
- 标签(service、host、metric)聚类
- 时间窗口(5 分钟内同一 service 的告警聚合)
- 根因分析(RCA 工具)步骤 4:建立值班机制
P0:主值班 + 备值班 + 主管(5 分钟响应)
P1:主值班(15 分钟响应)
P2:工单系统(1 小时响应)
P3:周会回顾(24 小时处理)
值班轮换:
- 主值班:7×24(每周轮换)
- 备值班:同主值班(接到升级通知介入)
- 主管:仅 P0 时介入步骤 5:定期 review 告警质量
每月 review:
- 告警数 / 有效告警数(告警有效性)
- 平均响应时间(MTTA)
- 误报率(误报告警 / 总告警)
- 漏报数(事故但未告警)
调整:
- 误报 > 30% → 提高阈值 / 加聚合
- 漏报 → 补充新告警
- MTTA > 目标 → 调整值班机制常见反模式
反模式 1:所有告警都 P0
症状:所有异常都标 P0
后果:告警疲劳,真正 P0 时没人响应
正解:严格区分 P0/P1/P2/P3反模式 2:固定阈值不考虑业务时间
症状:"CPU > 90%" 24×7 告警
后果:业务低峰时误报
正解:分时段阈值(如高峰期 / 低峰期)反模式 3:没有滞回
症状:阈值 CPU > 80%
后果:CPU 在 80% 附近频繁进出告警
正解:进入 80% / 退出 70%(滞回带 10%)反模式 4:告警没有聚合
症状:一个数据库问题触发 100 条告警
后果:告警风暴,淹没真正问题
正解:按 service/host/根因聚合工程实例:分级告警配置
【服务可用性】
P0:
alert: ServiceDown
expr: up{job="order-service"} == 0
for: 1m
labels: {severity: P0}
annotations: {summary: "订单服务完全宕机"}
P1:
alert: ServiceDegraded
expr: http_requests_total{status=~"5..",job="order-service"} / http_requests_total{job="order-service"} > 0.05
for: 5m
labels: {severity: P1}
【性能指标】
P2:
alert: HighLatency
expr: histogram_quantile(0.99, http_request_duration_seconds_bucket{job="order-service"}) > 0.2
for: 10m
labels: {severity: P2}
【资源预警】
P3:
alert: CPUWarning
expr: cpu_usage{job="order-service"} > 0.7
for: 1h
labels: {severity: P3}性能指标
告警体系健康指标
| 指标 | 设计目标 | 衡量方法 |
|---|---|---|
| MTTA | P0: 5min, P1: 15min, P2: 60min | 告警时间 vs 响应时间 |
| MTTR | P0: 30min, P1: 2h | 故障恢复时间 |
| 告警有效性 | 有效告警 / 总告警 > 70% | 告警 review |
| 误报率 | 误报 / 总告警 < 20% | 告警 review |
| 漏报数 | 0 | 事故复盘 |
| 告警疲劳度 | 值班工程师每周告警数 < 100 | 工单统计 |
监控设计
关键监控:
- 告警数量(按级别、按 service)
- MTTA / MTTR 分布
- 值班响应时间
- 告警聚合率
- 误报 / 漏报统计
告警本身也要被监控:
- 监控系统的可用性
- 告警推送通道的可达性
- 值班人员的状态边界判断
何时不用
场景 1:业务极简
- 单进程应用
- 没有分布式假设
- 没有用户感知的影响
→ 不需要复杂分级告警,简单 up/down 即可场景 2:业务完全可控
- 所有异常都有人工处理
- 没有自动化响应需求
→ P0/P1 足够,P2/P3 可省略场景 3:业务创新期
- 业务模式在变
- 阈值难以确定
→ 简化告警,重点是收集数据与其他方法论的边界
| 相邻概念 | 区别 |
|---|---|
| 监控 | 监控是数据采集;告警是触发响应 |
| SLO | SLO 是目标;告警是偏离 SLO 时的信号 |
| 事故复盘 | 事故复盘是事后总结;告警是事中响应 |
| 限流 | 限流是主动控制;告警是被动通知 |
何时升级(更复杂的方法论)
当以下情况出现时,考虑更复杂的告警体系:
1. 告警数 > 1000/天 → 升级告警聚合 / 智能告警
2. 误报率 > 30% → 重新评估阈值 / 加机器学习
3. 业务规模指数增长 → 多级告警 / 业务方分级
4. 国际化多区域 → 区域独立告警 + 全局聚合关键洞察
告警不是越敏感越好——是越精准越好。
告警太多 = 告警疲劳 = 真正事故无人响应告警太少 = 告警失灵 = 业务受损无人知晓
控制论的智慧:
- 软硬激发搭配:紧急的硬触发,渐进的软触发
- 滞回设计:避免阈值附近的频繁切换
- 自激振荡警告:监控"告警本身"——避免系统陷入"狼来了"循环
相关链接
IDDD 对位
- 告警 = 事件触发 → 事件分发与一致性(Ch 8):Domain Event → Alert
- 阈值 = 不变量 → 聚合 4 规则(Ch 10):聚合不变量 = 告警阈值
- 频谱 = 事件流分布 → 频谱分析
核心:告警 = 不变量被破坏时的信号——IDDD 业务事件 + cybernetics 软硬激发同构。