2500 字
约 8 分钟
18
S17-A23 · 故障演练的真实性:这次演练到底验证了什么

一次演练被判定"成功":主库切到备库用了 40 秒,业务在 90 秒后恢复。复盘时有人问了一句"演练期间真实流量跑在哪",答案是没有真实流量——演练在独立的预发环境做,用的是造出来的数据。于是这次"成功"验证的只是"脚本能跑通",而不是"故障时能不能兜住"。

演练的价值不在"有没有做",而在它是否触及了真实系统的约束。隔离环境、造数据、只测happy path,这三件事任何一件成立,演练的结论就要打折。


1. 演练的四个真实性维度

维度 问题
流量真实性 有真实请求在跑吗
数据真实性 数据量与分布接近生产吗
依赖真实性 上下游是真实的还是桩
人员真实性 是值班的人在做,还是准备过的人

四个维度可以组合成一张"真实性分数",用来横向比较不同演练的信息量:流量真、数据真、依赖真、人员普通四项各算一分。分数低的演练不是白做,但它的结论只能支撑很窄的决定。

第四项最容易被忽略:演练常常由"最熟悉这套系统的人"执行,而真实故障发生在凌晨、由不熟悉的人处置。演练测出的时长,往往比真实情况乐观一倍以上。

2. 四档演练的代价与收益

档位 做法 能验证
桌面推演 只讨论流程 分工与决策路径
隔离环境演练 独立环境跑脚本 脚本与工具可用
影子/只读演练 生产只读侧演练 观测与告警链路
生产灰度演练 小比例真实流量 端到端可用性

四档之间是"信息量"的阶梯,不是"要不要认真"的阶梯:低档演练做扎实也有价值,因为它验证的是分工与沟通;而高档演练若准备草率,反而会制造事故。

第三档是性价比拐点:在生产上做只读或小比例的真实演练,比在隔离环境做全流程演练更有信息量。代价是需要更强的熔断与回滚保障。

还有一个成本维度值得算:演练本身的代价。它占用工程与业务时间、承担轻微风险、可能引发真实告警。所以"做一次"这件事必须有明确要回答的问题——没有问题,它只是仪式。

3. 演练该验证的五件事

目标 判据
发现能力 告警在多长时间内触发
定位能力 从告警到定位到组件用了多久
处置能力 切换/回滚动作能否按预期执行
恢复判据 什么现象说明"恢复了"
沟通链路 谁通知谁、多久一次

恢复判据要写成可观测的条件,而不是"看起来正常":

// 恢复判据:三档,逐档确认
L1 技术恢复:主库可写、复制延迟 < 1s、连接数回落至基线
L2 业务恢复:错误率 < 0.1%、下单成功率回到基线 ±5%
L3 用户体验恢复:客服工单量回落到日常水平
// 三档都满足才算"恢复";只满足 L1 时说"技术上恢复",不说"恢复"

第四项最常缺失:很多演练在"动作执行完"就宣布结束,而没有定义"什么时候算恢复"。结果真实故障里,团队在动作做完后仍不知道该不该继续观察。

4. 让演练不伤生产的三道保险

保险 作用
明确的熔断条件 指标恶化到阈值立即终止
可回滚的每一步 任何一步都能撤回
有人专职踩刹车 有人只负责看指标

踩刹车的人还需要一个"提前终止"的判据:不是等到指标恶化才停,而是在"看起来要恶化"时停。演练的价值不高于一次真实故障的代价。

第三项是组织要求:执行演练的人不能同时负责判断"要不要停",因为他正忙于操作。必须有一个只看指标、有权叫停的人。

// 演练单的三项前置
abort_if:                        // 熔断条件,先写后做
  - error_rate > 1%
  - p99 > 2 × baseline
  - 任一 P1 告警
rollback: "bin/switch.sh --to blue && bin/verify.sh"
brake_owner: "李四(只看指标,不参与操作)"

演练还要考虑"谁来观摩":让不参与执行的相邻团队旁听,往往能发现沟通断点。执行者自己很难察觉"我没通知到谁",因为在他的视角里那就是全部。

// 演练角色的最小集合
执行人:按单操作(1–2 人)
踩刹车:只看指标,有权终止(1 人)
观察员:相邻团队代表,记录沟通断点(1 人)
记录员:时间线,精确到分钟(可由观察员兼任)

5. 演练结论怎么写才有用

写法 价值
"演练成功" 几乎为零
"切换耗时 40 秒,业务中断 90 秒" 中
上一条 + "本次未覆盖:真实流量、跨机房、夜间人手" 高
上一条 + "下次演练要补的三项" 最高

第三行的"未覆盖"是结论的主体:它告诉读者这次结论的适用范围。没有它,"成功"会被当成"这类故障我们都能扛"。

// 演练结论:以"未覆盖"为主体的写法
drill: db-failover
result:
  measured: { switch: 40s, recovery: 90s }
  covered: [主库不可用, 备库切换脚本, 告警触发]
  not_covered: [真实流量, 跨机房延迟, 夜间值班人手]
  conclusion: "脚本可用;可用性结论不成立,需生产灰度演练后再评估"
next:
  - "生产只读侧演练,验证真实流量下的表现"
  - "补一次夜间时段的桌面推演"

演练的时间选择也是真实性的一部分:总在下午做的演练,永远测不出夜间的人力约束。合理做法是把一部分演练放在非工作时段,哪怕只做桌面推演。

// 演练排期:按时间维度覆盖
每季度 1 次生产灰度演练(低峰,真实流量)
每季度 1 次夜间桌面推演(验证人员与升级链路)
每年 1 次跨机房/跨区域演练(依赖真实性)

6. 排错:五种"演练通过但故障时不行"

现象 成因 处理方向
演练顺利、真实故障混乱 执行人是熟手 换成值班的人做
切换成功但业务没恢复 未定义恢复判据 演练单加"恢复判据"栏
演练中出了新故障 无熔断条件 先写 abort_if
数据量太小看不出问题 造数据 用生产数据脱敏或影子
每次演练结论都一样 只测同一路径 换故障场景

演练的场景设计要有"难度阶梯":从单点故障到组合故障。单组件挂掉是第一级,组件挂掉 + 流量翻倍是第二级,再加上值班人手不足是第三级。多数团队的演练长期停在第一级。

第五项说明演练在"重复确认已知事实":如果连续三次演练都没有发现新问题,说明场景设计已经失效,该换更苛刻的场景,而不是继续做同样的。

7. 边界:什么情况不必做高保真演练

场景 为什么 做法
单实例、无高可用设计 无切换可演 只做恢复演练
影响面极小的内部系统 代价高于收益 桌面推演
已有真实故障复盘可参考 信息已获得 用复盘代替
演练成本超过预期损失 不划算 明确接受风险

还有一条与节奏有关的边界:演练频率不必与系统规模成正比,但与变更频率相关。系统改得多,故障模式就变,演练该跟上;半年没改动的系统,重复演练同一场景的信息量接近零。

判断口径一句话:这次演练的结论会被用来支撑什么决定。只支撑"脚本能跑",隔离环境就够;支撑"能不能扛住故障",就必须有真实流量。


8. 自测

  1. 演练的四个真实性维度中,哪一个最容易被忽略?为什么它会让时长结论系统性偏乐观?
  2. 四档演练里,哪一档是性价比拐点?它需要什么额外保障?
  3. 五个验证目标中,哪一项最常缺失?缺失会导致真实故障中出现什么问题?
  4. 为什么"执行演练的人"不能同时负责"判断要不要停"?
  5. 演练结论里"未覆盖"为什么是主体?没有它会怎么被误用?
  6. 连续三次演练都没有新发现,说明什么?该怎么调整?
S17-A23 · 故障演练的真实性:这次演练到底验证了什么
https://www.clxhxhhr.top/posts/6442/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。