3. 混沌工程实验设计:假设驱动实验、实验对象选择、实验计划制定
好,咱们进入正题。实验设计这块,说白了就是回答三个问题:炸什么?怎么炸?炸完怎么收场? 我见过太多团队,一上来就搞个大新闻——直接把数据库主库给 kill 了,结果线上告警炸锅,老板拎着刀来找你。嗯,这其实不是混沌工程,这是自杀式袭击。
我个人习惯,做实验之前先问自己一句:“我想验证什么?” 而不是“我想搞坏什么”。这个心态的转变,是专业和业余的分水岭。
3.1 假设驱动实验:先有猜想,再动手
混沌工程不是瞎搞。它本质上是一种科学实验。科学实验的第一步是什么?是提出假设。
举个例子。你写了一个交易系统,核心链路是:
客户端 -> 网关 -> 订单服务 -> 数据库。
你的假设可能是:
“当订单服务响应变慢(延迟 500ms),网关的熔断机制能在 3 秒内触发,保护数据库不被拖垮。”
这个假设很具体。它有明确的实验变量(延迟 500ms)、预期行为(熔断触发)、时间窗口(3 秒内)。
当 [故障条件] 发生时,[系统组件] 应该能在 [时间/条件] 内,表现出 [预期行为]。
我在项目中遇到过一种情况:团队写了个假设叫“系统应该高可用”。这其实不是假设,这是口号。你没法验证它。你得拆解成“当一台订单服务宕机,Nginx 反向代理能在 5 秒内将流量切到另一台,丢单率不超过 0.1%”。
3.2 实验对象选择:服务、数据库、网络
假设有了,接下来选靶子。交易系统里,我一般把实验对象分成三层:服务层、数据层、网络层。每一层的玩法不一样。
3.2.1 服务层:进程、实例、容器
服务层是最容易下手的。说白了就是让某个服务“不好好干活”。
- 进程级故障: kill -9 杀掉进程。验证进程守护和自动拉起。
- 实例级故障: 停掉一个 Pod 或虚拟机。验证负载均衡和流量调度。
- 依赖故障: 让服务 A 调用服务 B 时返回 500 或超时。验证熔断和降级。
我个人建议,先从依赖故障开始。为什么?因为它最接近真实场景。交易系统里,下游的行情服务、风控服务、清算服务,任何一个挂了,你的核心交易逻辑都得扛住。
3.2.2 数据层:数据库、缓存、消息队列
数据层是交易系统的命根子。这里动手要格外小心。
| 对象 | 实验类型 | 验证目标 |
|---|---|---|
| MySQL/PostgreSQL | 主库延迟、连接池耗尽、磁盘写满 | 读写分离是否生效、连接池回收机制 |
| Redis | 缓存击穿、主从切换、内存淘汰 | 缓存降级策略、数据一致性 |
| Kafka/RocketMQ | Broker 宕机、消息积压、消费延迟 | 消息不丢失、消费幂等性 |
我记得有一次做数据库实验,我们模拟了主库 CPU 打满的场景。结果发现,从库的查询延迟从 2ms 飙到了 800ms。为什么?因为主库的 binlog 同步线程抢不到 CPU,导致从库一直等 binlog。这个发现直接让我们优化了主从同步的线程优先级。
3.2.3 网络层:延迟、丢包、分区
网络故障是最隐蔽的。它不像服务宕机那么明显,但破坏力极大。
- 网络延迟: 给某个服务加 100ms 延迟。验证超时配置是否合理。
- 网络丢包: 丢包率 1%、5%、10%。验证重试机制和幂等性。
- 网络分区: 把一组机器从网络上隔离。验证集群脑裂保护。
你想想看,交易系统里最怕什么?不是服务挂了,而是服务半死不活。比如网络延迟 200ms,服务没挂,但所有请求都超时重试,结果流量放大 10 倍,直接把整个集群打崩。这就是典型的“雪崩效应”。
3.3 实验计划制定:从爆炸半径到回滚方案
实验计划不是写作文,是操作手册。你得让一个刚入职的运维照着你的计划,也能把实验跑完。
我一般把实验计划分成五个步骤:
- 定义爆炸半径: 这个实验会影响多少用户?多少交易?影响面能不能控制在 1% 以内?
- 设置观测指标: 成功率、延迟、错误率、吞吐量。每个指标都要有阈值。
- 准备回滚方案: 如果指标超过阈值,怎么快速恢复?是重启服务?还是切流量?
- 执行实验: 先灰度,再小流量,最后全量。别跳步。
- 复盘总结: 实验发现了什么?系统有什么改进点?
这里我画了一张图,帮你理清整个实验设计的流程:
这张图的核心逻辑是:实验是一个闭环。你提出假设,选择对象,制定计划,执行,复盘,然后根据复盘结果提出新的假设。如此循环,系统的韧性才会越来越强。
第一次实验,爆炸半径控制在 1% 以内。比如 100 台机器,先搞 1 台。1000 个用户,先搞 10 个。等你有信心了,再慢慢扩大。别想着一步到位,混沌工程是马拉松,不是百米冲刺。
最后,关于实验计划,我建议你写一个检查清单。每次实验前,逐项确认:
- ✅ 假设是否清晰可验证?
- ✅ 实验对象是否明确?
- ✅ 爆炸半径是否可控?
- ✅ 观测指标是否到位?
- ✅ 回滚方案是否就绪?
- ✅ 是否通知了相关团队?
嗯,这个清单看起来简单,但每次实验前过一遍,能帮你避免 90% 的线上事故。我自己就吃过亏——有一次忘了通知运维团队,结果他们看到告警直接重启了集群,把我的实验给打断了。从那以后,我每次实验前都会在群里吼一声:“兄弟们,我要搞事情了,别慌。”
公众号:蓝海资料掘金营,微信deep3321