半夜被叫醒,打开监控发现是某台机器磁盘 81% 的阈值告警,服务一切正常。这类事故不发生在系统里,而发生在机制里:告警没有判据、响应没有角色、复盘没有出口。值班体系的价值不是“有人接电话”,而是把一次故障压缩成可重复的流程。
1. 告警的三条判据
| 判据 | 问题 | 不合格的样子 |
|---|---|---|
| 可行动 | 收到后有没有明确动作? | “CPU 高了”,但无处置口径 |
| 有归属 | 谁负责响应? | 群里 20 人,没人认领 |
| 有分级 | 要不要现在处理? | 全部 P0,等于没有分级 |
症状告警优于原因告警:用户侧错误率、延迟、成功率是症状;CPU、连接数、GC 次数是原因。原因指标适合做面板与下钻,不适合做叫醒人的依据——原因很多,症状只有一个。
# 症状型告警占位(用比率而非绝对值,避免流量变化导致误报)
- alert: APIErrorRateHigh
expr: sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
for: 10m
labels: {severity: P2, owner: TEAM}
annotations: {runbook: "RUNBOOK_URL"}
for 的作用是压掉瞬时抖动,但它也延长了发现时间:P0 类告警的 for 应当短,P2 可以长。
2. 告警疲劳的量化与降噪
| 指标 | 口径 | 典型健康区间(按自身基线校准) |
|---|---|---|
| 每日告警数 | 去重后的告警条数 | 值班人能逐条看完 |
| 有效比例 | 需要人工动作的比例 | 越高越好,低于三成说明噪声大 |
| 首次响应时间 | 从触发到有人接手 | 与分级匹配 |
| 夜间告警占比 | 落在休息时段的条数 | 越低越好,反映阈值与分级 |
降噪三件套,作用不同,别互相替代:
| 手段 | 作用 | 风险 |
|---|---|---|
| 聚合 | 同一根因的多条合成一条 | 聚合过宽会掩盖真实差异 |
| 抑制 | 上游故障时抑制下游告警 | 抑制规则写错会静默丢失告警 |
| 静默 | 计划内维护窗口 | 忘记解除,故障期无人知晓 |
# 抑制规则示意:数据库不可用时,不再逐条报业务 5xx
- source_match: {alertname: "DBDown"}
target_match: {alertname: "APIErrorRateHigh"}
equal: ["cluster"]
静默要有自动过期,否则维护窗口结束后它们会变成永久盲区。
3. 值班的成本结构
| 成本 | 表现 | 缓解 |
|---|---|---|
| 注意力碎片化 | 白天做不了深度工作 | 明确值班日不做长任务 |
| 上下文重建 | 每次被叫醒要重读系统 | 值班手册 + 最近变更清单 |
| 跨时区 | 交接含糊导致漏看 | 书面交接,含未闭环项 |
| 单点依赖 | 只有一个人会处理 | 至少两人能处置,定期轮换 |
| 长期疲劳 | 隐性离职原因 | 控制夜间告警数,而非发补贴 |
值班表的第一原则不是公平,而是排班期内有人能处置。只有一个人会看的那套系统,轮换只是形式。
4. 故障分级与响应角色
| 级别 | 判定 | 响应方式 | 沟通节奏 |
|---|---|---|---|
| P0 | 核心功能不可用或数据受损 | 立即全员,指挥上线 | 每 15–30 分钟 |
| P1 | 主要功能降级、有绕行方案 | 立即,负责人主导 | 每 30 分钟 |
| P2 | 局部异常、影响有限 | 工作时间内处理 | 按需 |
| P3 | 无用户影响 | 排期修 | 不需要 |
角色分工(人少时一人兼多职,但要写明)
指挥 IC 决定优先级、决定是否回滚、控制变更
操作 Ops 执行命令与配置变更(同一时间只有一双手)
沟通 Comms 对外说明、对内同步,不参与排障
记录 Scribe 时间线、决策、证据(复盘唯一可信来源)
最常缺的是“记录”这个角色。没有时间线,复盘只能靠回忆,而回忆在压力下会系统性偏向“我当时就怀疑是它”。
5. 止血与定位的顺序
00:00 发现 告警/用户反馈 → 确认影响面(谁受影响、多严重)
00:05 分级 定级 + 拉人 + 宣布 IC
00:10 止血 回滚 / 切流 / 扩容 / 关功能开关(选一个,别叠三个)
00:25 确认 症状是否消失(用户侧指标,不是原因指标)
00:40 定位 在症状已缓解的前提下找根因
排障时不要同时改三样。同时回滚 + 扩容 + 改配置,症状消失后无法判断哪一步生效,下一次还会复发。一次只改一个变量,改完看症状指标。
止血手段按可逆性排序:功能开关 > 切流/降级 > 回滚 > 扩容 > 重启。重启排最后,因为它销毁证据。
6. 对外沟通的模板与节奏
【故障通告 · P1】
现状 某功能部分用户无法使用(约 X% 请求失败),其余功能正常
影响 受影响用户、时间范围
已做 已回滚至上一版本 / 已切至备用链路
下一步 继续观察 30 分钟,若未恢复将执行 PLAN_B
下次更新 时间点(必须给)
三条纪律:用户视角(说“无法下单”而不是“Redis 连接池耗尽”);给下次更新时间(不给会引来重复问询);不承诺没掌握的结论(“预计 10 分钟恢复”在没有依据时是最贵的承诺)。
内部同步与外部通告要分开写:前者要技术细节,后者要影响与预期。
7. 依赖方故障:等还是绕
| 情况 | 判断 | 动作 |
|---|---|---|
| 依赖方已公告、有明确恢复时间 | 等 | 降级非核心功能,保留核心链路 |
| 依赖方无公告、症状持续 | 绕 | 切备用链路或本地兜底 |
| 绕行需改代码 | 先降级 | 排障期不改代码,用开关 |
| 绕行会导致数据不一致 | 等 + 限流 | 不一致的代价常高于短暂不可用 |
| 只有单一依赖 | 提前建兜底 | 事后补:这是架构债 |
判断的核心是代价对比:绕行引入的不一致、双写、脏数据,往往比“等 30 分钟”更贵。
8. 复盘:无责、看机制、给可执行项
| 做法 | 正确 | 形式化信号 |
|---|---|---|
| 归因 | 看机制缺位,而非个人失误 | 结论是“某人粗心” |
| 范围 | 时间线 + 决策点 + 失效点 | 只有一段叙述性文字 |
| 改进项 | 有负责人、截止、验证方式 | “加强监控”“提高意识” |
| 参与人 | 当事人在场并主导叙述 | 当事人缺席,被他人代述 |
复盘模板(占位)
1 影响:用户侧现象、持续时间、影响面
2 时间线:发现 / 分级 / 止血 / 恢复 / 各决策点与依据
3 失效点:为什么没更早发现、为什么没更快止血
4 改进项:ID、负责人、截止、验证方式、优先级
5 不做什么:明确本次不修的项与原因
“加强监控”不是改进项,因为它无法验证。可执行项的形式是:改哪个文件/哪条规则、谁做、什么时候做完、怎么证明做完。
9. 改进项的跟踪
ID 描述 负责人 截止 验证方式 状态
A-1 增加下单成功率症状告警 Ops DATE 故障注入后 1 分钟内触发 open
A-2 回滚脚本纳入演练 Ops DATE 演练记录 open
A-3 依赖超时从 30s 降为 3s Dev DATE 配置 diff open
跟踪的两个失效点:没有验证方式(改完不知道算不算改好)、没有过期机制(三个月后自动消失)。改进项应当和普通需求进同一个队列,否则它永远是“下次再说”。
10. 演练与混沌实验的边界
| 条件 | 是否值得做 |
|---|---|
| 有明确假设(“切流能在 1 分钟内生效”) | 值得 |
| 无回滚预案 | 不值得,先补预案 |
| 生产环境无旁路、无灰度 | 不值得,先在预发做 |
| 团队第一次接触故障流程 | 值得,先做桌面推演 |
| 关键依赖只有一个实例 | 不值得,先做冗余 |
演练的产出不是“通过了”,而是发现了流程里的卡点:找不到开关、权限不足、通知发不出去。这些在真实故障里会成倍放大。
11. 度量:三个数就够
| 指标 | 定义 | 用途 | 陷阱 |
|---|---|---|---|
| MTTD | 从故障发生到被发现 | 衡量发现能力 | 依赖“发生时间”的准确认定 |
| MTTR | 从发现到恢复 | 衡量止血能力 | 恢复定义要统一(症状消失 vs 根因修复) |
| 重复故障率 | 同类故障再次发生的比例 | 衡量改进是否生效 | 分类口径不稳定则不可比 |
MTTR = 平均(恢复时间 - 发现时间) # 明确“恢复”指症状消失
重复故障率 = 同类二次故障数 / 同类故障总数 # 按固定分类表统计
不要用 MTTR 单独评价团队:延长观察窗口可以降低 MTTR,缩短观察窗口可以降低重复故障率,两个指标都能被“优化”。
12. 排错
| 现象 | 原因 | 处理 |
|---|---|---|
| 告警很多但没人动 | 无归属、无分级 | 每条告警补 owner 与 severity |
| 故障后无人指挥 | 角色未定义 | 定 IC 角色,值班表里写明 |
| 复盘结论都是“加强监控” | 缺可执行项规范 | 强制负责人 + 截止 + 验证 |
| 同类故障反复出现 | 改进项未跟踪 | 改进项进需求队列 |
| 夜间告警不断 | 阈值静态、未做聚合 | 改比率告警 + 抑制规则 |
| 交接后漏处理 | 交接无书面记录 | 交接单含未闭环项 |
13. 边界
| 场景 | 判断 |
|---|---|
| 单机小服务 | 不需要值班体系,配基础告警即可 |
| 无人可叫(一人团队) | 优先做自动化恢复,而非排班 |
| 流程过重 | 会被绕过,宁可少环节但都执行 |
| 故障极低频(季度级) | 桌面推演优于实战演练 |
| 团队尚无监控 | 先补症状指标,再谈流程 |
流程的检验标准是“慌的时候还能照着做”:需要翻文档才能想起下一步的流程,在故障里一定失效。
14. 自测
- 为什么症状告警优于原因告警?
- 有效告警比例低意味着什么,先改哪一项?
- 止血阶段为什么不能同时改三样?
- 对外通告里为什么必须给出下次更新时间?
- “加强监控”为什么不算改进项?
- MTTR 和重复故障率各自能被怎样“优化”而失真?