Skip to content

混沌工程与故障演练 ​

定位:金融级稳定性方法论(4/6)。预案的可靠性不能等真故障来验证——混沌工程是"在生产可控地制造故障,证明系统真的扛得住"。本篇写:从随机猴子到定向注入的演进、稳态假设与实验设计(现金流量注入的金融特殊性)。同时写演练三级体系与组织心智建设。前置阅读:应急预案三板斧-限流降级切流(演练验证的对象)。SLO 与稳定性工程(稳态来自 SLI)。容量规划与全链路压测(压测与混沌的分工)。

一、从 MonkeyOps 到定向故障注入 ​

随机猴子          ──►   定向故障注入        ──►   攻防演练
(发现"会发生的")         (验证"最担心的")           (暴露"没想到的")
杀随机实例               指定杀 DB 主从/断可用区     红蓝对抗,不告诉蓝军细节
  • 随机猴子(Netflix Chaos Monkey 一系:随机杀实例):价值是暴露"随机会发生的问题"——单点部署、启动慢、健康检查缺失。代价低,适用互联网型无状态服务。
  • 定向注入(ChaosBlade/ChaosMesh 类工具):金融系统不能随机搞——每次注入都是一次受控风险。实验必须针对"最担心的故障清单"设计:DB 主备切换丢不丢事务?同城断网后单元路由多久收敛?风控依赖超时降级方向对不对?
  • 攻防演练:红军出题(注入组合故障),蓝军值守(只能用预案库和生产工具应对)。这种形式最接近真实故障的混乱度。

金融场景的排序是倒过来的:先定向(风险可控、验证已知担忧),再攻防(组织能力成熟后)。随机猴子在资金链路上几乎不用。

二、稳态假设:实验设计的起点 ​

混沌实验不是"搞坏一个东西看看",是用故障验证一条稳态假设:

稳态假设句式:
  当 <故障注入> 发生时,
  <业务 SLI> 仍保持 <目标范围>,
  因为 <系统应有的保护机制>。

例:当账单库主库故障切换时,
    账单日扣款成功率仍 ≥ 99.5%(切换窗口内下降不超过 0.3%),
    因为主从切换 < 30s 且扣款侧有失败重入队列。
  • 稳态选业务 SLI,不选资源指标:"切换期间 CPU 没飙高"验证不了业务连续性。稳态是"放款成功率、扣款成功率、P99"这条线。SLI 的选法见 SLO 与稳定性工程,怎么被观测见 观测性三件套。
  • 假设要落到"因为":没有"因为"的假设测不出保护机制是否真的存在。如果稳态只是"没出事",可能只是故障没生效(注入失败也是实验结果,要能区分)。
  • 反例:没有稳态假设的混沌工程 = 合法地搞破坏;注入了故障、看了一眼监控没炸就收工,等于什么都没验证。

三、实验设计:爆炸半径与金融特殊性 ​

一张实验卡片要写全六件事:

┌────────────────────────────────────────────────┐
│ 假设:见上节句式,含"因为"                        │
│ 动作:kill / 断网 / 慢注入 / 时钟偏移 / 磁盘打满   │
│ 爆炸半径:1% 实例 → 单可用区 → 单元,逐级放大      │
│ 护栏:SLI 越界自动中止(如成功率跌破 99.5% 立即停)│
│ 回滚:注入的解除动作 + 生效确认方式                │
│ 观察:实验窗口、记录哪些指标与日志                  │
└────────────────────────────────────────────────┘

常见注入手段速查:

类别手段典型验证目标
资源杀进程 / 容器 OOM / 磁盘打满优雅退出、磁盘水位告警、日志降级
网络延迟 / 丢包 / 断可用区超时与重试配置、熔断阈值、切流收敛时间
依赖慢注入(不挂,只变慢)线程池隔离、慢依赖是否拖垮主链路
数据主从切换 / 时钟偏移切换零丢数据、计息的跨天与时区正确性
应用抛异常 / 强制启用熔断降级方向是否安全侧、兜底逻辑是否安全

"慢注入"最容易被忽略也最致命:多数故障不是"挂了"而是"慢了"。挂了会被熔断快速隔离,慢了会占住线程池拖垮全局。延迟信号对照 观测性三件套,连接池排队对照 问题定位步骤。

现金流量注入的金融特殊性(这一节是金融与互联网混沌工程的分水岭):

  • 生产环境不注入"会动真钱"的故障场景。重复扣款、超额放款、幂等失效这类验证,用内部沙箱账户或影子流量做。验证的是机制(幂等键、额度锁、事务约束),不冒真实资险。
  • 第三方渠道永不注入:征信、卡组织、清算网络。注入等于把演练变成生产事故加合规事件,一律用挡板模拟其故障。
  • 故障注入要挑时间窗:避开账单日与大促窗口。错误预算本来就紧(见 SLO 与稳定性工程 的预算联动)。反过来,大促前的演练要包含"预案触发"的验证(与 容量规划与全链路压测 的 120% 超额档衔接)。
  • 反例:为验证"重复扣款防护",在准生产环境直接重放生产扣款消息且未加幂等隔离——演练本身制造了资损。实验设计的评审标准比功能发布更严,因为它是主动引入的故障。

四、演练分级:桌面推演 / 局部注入 / 全链路攻防 ​

级别形态频率验证目标准入条件
L1 桌面推演会议室纸面走预案:谁判断、谁按按钮、谁通报季度,覆盖全部 P1/P2 预案组织与流程通不通、人员知不知道预案在哪无(最低成本,新预案必经)
L2 局部注入单服务/单依赖/单实例故障注入月度单个保护机制真实有效(熔断阈值、降级方向)稳态假设 + 护栏就绪
L3 全链路攻防红蓝对抗,组合故障,可含摘可用区/机房级年度 + 大促前1-5-10 全流程、预案联动、组织协同L2 通过率达标 + 预授权机制生效

分级的价值在于成本与收益匹配:L1 用最低成本让预案从"文档"变成"人的记忆"。L3 一年一两次,每次都应暴露真问题。如果攻防演练"零发现",不是系统完美,是红军出题太软。

演练角色分工(L2/L3 必须配齐):

角色职责关键纪律
红军(出题方)设计故障、把握注入节奏对蓝军隐藏细节,只按卡片护栏行动
蓝军(值守方)用预案库与生产工具应对禁止临时写代码,只能用预授权手段
裁判记录时间线、判稳态是否守住中立,越界即喊停
观察员各域盯盘,标记异常但不干预事后输出"差点越界"的 near-miss 清单

五、组织心智建设 ​

  • Blameless:不追责个人,追责流程。演练暴露的每个问题都归到"哪个环节失守"(设计/预案/监控/工具)。归到人的复盘会让下一次故障被隐藏到不可收拾。
  • 故障是常态,要写进设计期。方案评审必答"这个依赖挂了会怎样"(见 如何出一个技术方案 的异常与降级节)。混沌工程的结果要反向改变设计方案。

三个可落地的组织动作:

  • 故障演练日:每月固定一天全技术部门范围做 L2,形成公众事件而非各团队自发行为;

  • 复盘公开:故障与演练的复盘对全部门可见(含失败案例),可见性本身就是质量压力;

  • 新人第一课:新架构师入职三个月内必须以蓝军身份参加一次 L3。这比读十篇文档更能建立对系统边界的直觉。

  • 度量演练本身:预案命中率(真故障时可用预案覆盖的比例)、演练发现问题的闭环率、MTTR 趋势。三者见 应急预案三板斧 的 1-5-10 分解。只统计"演练次数"的团队,练的是汇报能力。

  • 反例:演练变成表演——提前一周通知、挑流量最闲的时段、注入最轻的故障、蓝军提前背好剧本。报告很漂亮,系统依旧脆弱。对抗性是演练有效的前提:蓝军不知道细节,才是在练系统而不是在演节目。

把演练放进日历,而不是想起来才做。L1 季度覆盖全部 P1/P2 预案(账单日前两周完成,留出修复窗口)。L2 月度按域轮转。L3 固定在大促前 6 周与年末各一次——离大促太近没有修复时间,太早则紧迫感不足。

六、从演练到改进的闭环 ​

演练的产出不是报告,是进问题库的改进项:

演练发现 ──► 分级入库 ──► 指派 owner ──► 修复或预案兜底 ──► 下轮演练复验
                │
                ├─ A 类:保护机制缺失(如熔断没配)──► 立即修复
                ├─ B 类:机制存在但阈值/开关失配 ──► 修正 + 更新预案库
                └─ C 类:架构性缺陷(如单点)─────► 转 ADR 立项
                                                  (见[技术决策与ADR](技术决策与ADR.md))

度量闭环健康度的两个数:问题闭环率(发现后 30 天内关闭的比例,目标 > 90%)。以及预案命中率(下次真故障时可用预案直接覆盖的比例,对照 应急预案三板斧 的预案库)。只练不闭环的混沌工程,是付费制造焦虑。

追问链 ​

混沌工程和全链路压测有什么区别?

压测问"能扛多少"(容量维度,负载是正常请求的放大)。混沌问"坏了会怎样"(韧性维度,负载正常但组件故障)。两者在大促前衔接:压测的 120% 超额档顺带验证限流预案。混沌的 L3 攻防复用压测的流量水位做背景。只做压测的团队知道天花板在哪,不知道塌了之后会发生什么。

怎么说服业务方同意在生产做故障注入?

三步:先在准生产/沙箱流量上取得成绩(用发现的真实问题建立信任)。再从小爆炸半径进生产(1% 实例、白名单流量、SLI 护栏自动中止)。把"注入窗口避开业务高峰"写成制度。业务方真正怕的不是注入,是不可控——把爆炸半径、护栏、回滚摆到桌面上,谈判就容易了。

演练发现的问题总是修不完,怎么办?

按资损优先级排序而不是按发现顺序修。影响核心 SLI 且预案缺口的问题先修(对照 SLO 与稳定性工程 的定级表)。修不完的必须有临时缓解预案兜底进预案库。发现多不是坏事,发现多且闭环率低才是。

演练和真实故障永远有差距,练了真能用吗?

差距主要在"心理"与"信息混乱度":真实故障没人告诉你发生了什么,演练有裁判递题。缩小差距靠两条:L3 蓝军不提前知道场景与时间(突袭式)。复盘时对比"演练的定位路径"与"上次真故障的定位路径",差在哪补哪。多数差距最后都落在监控可视化上(见 观测性三件套)。演练练的不是剧本是肌肉记忆:预案按钮在哪、通报发给谁,练过和没练过,前 5 分钟就是天壤之别。

一句话总结 ​

混沌工程 = 稳态假设 + 受控故障 + 护栏回滚。它验证的不是"系统会不会挂",而是"我们以为的保护机制是否真的存在且生效"。金融场景的底线是:不动真钱、不碰外部渠道、爆炸半径逐级放大。演练的价值密度取决于对抗性,剧本化的演练是表演。

2026-10 新增(金融级稳定性方法论系列)。