核心思想

主动在生产环境中注入故障,验证系统的韧性(resilience)。

为什么主动搞破坏:因为分布式系统的故障模式难以预测——你无法仅通过代码审查和测试,确信系统在某个组件失效时仍能正常工作。

混沌工程的信条:与其等待故障发生,不如主动制造它们(在可控范围内),从而:

  • 发现系统的弱点;
  • 验证监控和告警是否有效;
  • 验证自动恢复机制是否工作;
  • 让团队熟悉应急流程。

起源

Netflix 是这一领域的先驱。

2011 年前后,Netflix 在向 AWS 云迁移的过程中,面临"云实例可能随时失效"的现实——因此设计了 Chaos Monkey:在生产环境中随机关闭服务实例,强迫工程师构建能容忍实例失效的系统。

后来发展成 Simian Army(猿猴军团),包括更丰富的故障注入工具。

与其它实践的区别

目标方式
测试验证"功能是否符合预期"已知输入 → 验证输出
混沌工程验证"系统在异常条件下的行为"注入故障 → 观察系统表现

混沌工程是"实验",不是"测试"——你有一个假设("如果缓存挂了,系统会降级到数据库,响应时间增加但不会宕机"),然后通过实验验证或推翻这个假设。

实验流程

一、定义稳态(Steady State)

确定系统的正常行为指标(如 QPS、P99 延迟、错误率)。

二、提出假设

"如果 X 发生故障,系统指标 Y 会 Z。"

三、设计实验

  • 选择注入的故障类型;
  • 确定爆炸半径(影响范围)——从最小开始;
  • 确定中止条件(什么情况下立即停止实验)。

四、在小范围执行

先在一个服务、一个可用区、少量流量上做。

五、验证假设

对比实验期间与稳态的指标。

六、修复问题并再次验证

七、逐步扩大范围

常见的故障注入类型

基础设施层:

  • 随机关闭虚拟机/容器;
  • 关闭整个可用区(模拟 AZ 故障);
  • 磁盘填满;
  • 网络延迟、丢包、分区(Network Partition);
  • CPU / 内存压力。

应用层:

  • 杀死进程;
  • 使某个服务的响应变慢或返回错误;
  • 依赖服务不可用(如数据库、缓存、第三方 API);
  • 使时钟偏移。

Kubernetes 环境:

  • kubectl delete pod 的自动化版本;
  • 注入到特定 Pod 的网络故障;
  • 节点不可用。

工具

  • Chaos Mesh(CNCF 项目,K8s 原生);
  • LitmusChaos(CNCF 项目);
  • Gremlin(商业);
  • Chaos Monkey / Simian Army(Netflix 开源);
  • toxiproxy:用于模拟网络故障(Shopify 开源);
  • 云厂商提供的故障注入服务(如 AWS FIS)。

关键原则

一、从生产环境开始(但要小心)

混沌工程的倡导者认为:只有在生产环境才有意义——因为预发环境的流量模式、数据、依赖关系与生产不同。

但这需要前提:

  • 系统已具备一定的韧性(否则一注就全挂);
  • 有完善的监控和中止机制;
  • 团队有能力快速响应。

务实的做法:先在非生产环境验证实验脚本,再谨慎地进入生产,从最小爆炸半径开始。

二、最小化爆炸半径

第一次实验应该只影响:一个实例、一小部分用户、一个非关键功能。

三、始终有中止机制

  • 明确的指标阈值(如错误率超过 X% 立即停止);
  • 一个"大红按钮"(能立即停止实验并恢复)。

四、要有可观测性作为前提

没有监控,就不要做混沌工程——因为你无法判断实验的结果。

监控不到位时,混沌实验的结果是"什么都没观察到",而这毫无价值。

五、自动化与常态化

理想状态是持续运行混沌实验(如每隔一段时间自动注入故障),而不是一次性活动。

原因:系统在不断变化,上一次验证过的韧性,下次部署后可能就失效了。

一个常见误解

"混沌工程就是随机搞破坏。"

不是。 它是有假设、有控制、有度量的科学实验。

随机破坏只会带来混乱,不会带来认知。

一句话

混沌工程的价值,在于把"我们以为系统会怎样"变成"我们验证过系统会怎样"。

说明:本文为可靠性工程的知识整理。