故障演练核心原则
做故障演练,最怕什么?一上来就把整个生产搞崩了,然后老板找你喝茶。说白了,故障演练不是无差别轰炸,它需要一套核心原则来兜底。我最初接触混沌工程时,也觉得只要注入故障看系统反应就行,结果有一次直接炸了核心服务,全站告警响成一片……从那以后,我对这几个原则的理解就刻在骨子里了。
最小爆炸半径
原则一:控制影响范围,让它足够小。不要一上来就搞全集群瘫痪,先从一台机器、一个 Pod 开始。
我在项目中见过团队直接把故障注入到数据库主节点,导致整个读链路中断。为什么?因为没做范围隔离。最小爆炸半径要求你明确“这次演练最多影响到谁”,然后通过限流标签、灰度分组、防火墙规则等手段把爆炸包住。
常见的爆炸半径粒度如下表:
| 粒度 | 说明 | 适用场景 |
|---|---|---|
| 单实例 | 只影响一个容器或进程 | 功能验证、底层依赖测试 |
| 单可用区 | 影响某个AZ内的全部副本 | 区域故障转移演练 |
| 单用户群 | 只对特定标签的用户生效 | 灰度验证新特性容错 |
| 全集群 | 影响所有实例 | 罕见的全链路压测,需提前审批 |
渐进式演练
有了最小爆炸半径,怎么放大?一点一点来。渐进式演练,说白了就是“小步快跑,慢慢扩大”。
我见过一个团队跳过单节点测试,直接上全链路演练,结果熔断器没打开,整个系统雪崩。嗯,这种教训太痛了。
渐进式演练的典型步骤:
- 第一天:对单个非核心实例注入 10% 延迟,观察5分钟。
- 第二天:对单个核心实例注入 10% 延迟,观察10分钟。
- 第三天:对两个核心实例注入 30% 延迟,观察15分钟。
- 第四天:对整个服务组注入 50% 延迟,但只影响1%的用户。
你看,每次只改变一个变量。爆炸半径和严重程度交替扩大,才能安全地积累信心。
自动化
手动演练?一次两次还行,多了谁也受不了。自动化才是故障演练能持续跑起来的关键。
自动化不仅仅是写个脚本跑故障,它要包含:
- 自动化编排:定义故障注入的时机、目标、预期行为。
- 自动化验证:演练中自动检查SLO是否违反,如果触发了告警则自动停止。
- 自动化回滚:故障结束后自动恢复配置,清理残留。
- 自动化报告:生成执行摘要、指标对比、失败原因。
下面是一个基于 Chaos Mesh 的自动化演练 YAML 示例,只包含最小范围的网络延迟注入:
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: network-delay-test
spec:
action: delay
mode: one
selector:
namespaces: ["default"]
labelSelectors:
"app": "web-server"
delay:
latency: "200ms"
jitter: "50ms"
correlation: "50"
duration: "60s"
scheduler:
cron: "@every 2h"
自动化不只是工具,更是一种纪律。每次演练后把脚本放进 Git 仓库,带版本号,下次复用就能直接跑。
可观测性
没有可观测性,故障演练就是盲人摸象。你注入故障后,怎么知道系统“扛住了”还是“硬撑”?
可观测性需要三个维度:指标、日志、调用链。演练前一定要确保这些数据能实时拉取,延迟不能超过5秒。
下面是我常用的观测指标清单:
| 类别 | 关键指标 | 告警阈值(演练期间) |
|---|---|---|
| 响应 | P99 延迟 / 错误率 | 延迟>500ms 或错误率>1% 立即停止 |
| 资源 | CPU / 内存 / 网络 IO | 任何资源使用率>90% 持续30秒告警 |
| 业务 | 订单量 / 支付成功率 | 业务量下降>5% 自动熔断 |
| 依赖 | 下游服务调用成功率 | 调用成功率<95% 标记演练失败 |
可观测性还有一个作用:让团队看到“系统正在被揍”的实时画面,这比任何Postmortem都有说服力。
四原则的协同关系
这四个原则不是孤立存在的,它们形成一个闭环:最小爆炸半径让你安全地开始;渐进式演练帮你积累信心;自动化让整个过程可重复;可观测性确保你每次演练都能学到东西。缺一个,这个轮子就转不起来。
下面这张图总结了我心中的四原则关系:
这四个原则贯穿了故障演练的完整生命周期。有了它们,你才敢在生产环境里放火,并且保证烧完还能复盘优化。下一次动手前,先把这四个原则过一遍,你的演练就不会翻车。