混沌工程:故意破坏生产环境(从此不再出现故障)

发布: (2025年12月13日 GMT+8 18:00)
6 min read
原文: Dev.to

Source: Dev.to

2 AM 值班电话的故事

现在是凌晨 2:07。
🚨 生产宕机 – 错误率高

所有检查项都已勾选,系统标称“高度可用”,却只有一个节点挂掉了。
那天晚上教会我们一个痛苦的真理:纸面上看起来可靠的系统,并不一定能在真实故障中存活。

什么是混沌工程?

混沌工程 是一种有意破坏系统,以了解系统在故障下行为的实践。

通俗来说:在可控的窗口期内制造受控的故障——最好在安全时段——让生产环境不在凌晨 2 点给你上课。

为什么会有它

  • 现代系统是分布式的。
  • 故障是不可避免的。
  • 人类不擅长预测边缘情况。

混沌工程接受现实,而不是与之抗争。

传统测试的局限性

传统测试假设…现实情况…
依赖项表现正常数据库会变慢,而不仅仅是崩溃
网络可靠网络会撒谎,延迟会突增
延迟可预测第三方 API 随机超时
部分故障不会级联分布式系统会以创意的方式失效

大多数宕机源于 未知的未知,而不是代码 bug。混沌工程在用户遇到之前就揭示这些未知。

定义“健康”系统

  • 请求成功率
  • 延迟分位数
  • 错误预算
  • 业务 KPI

没有明确的稳态指标,你只是在盲目破坏。

真实的故障类型(非模拟)

  • 杀掉 pod
  • 添加延迟
  • 中断网络调用
  • 限制 CPU

这些操作 在生产环境 中使用真实流量、真实数据和真实混沌——逐步进行,在安全窗口期内,并配有回滚计划和预定的停机时间。

实验示例

# Kill a pod
kubectl delete pod payment-service-xyz
  • 在服务之间添加 500 ms 延迟
  • 丢弃 10 % 的数据包

暴露出的问题: 重试风暴、超时配置错误、数据库变慢、Redis 不可用、第三方 500 错误、CPU 限流、内存压力、磁盘已满等。

如何运行混沌实验

  1. 挑选关键服务
  2. 定义稳态指标(成功率、延迟、错误预算)
  3. 在非生产环境开始
    • 杀掉单个 pod
    • 观察一切
    • 修复薄弱环节
  4. 重复并扩大
    • 在低流量时搬到生产
    • 给依赖添加延迟
    • 模拟数据库慢速

小规模、受控的混沌胜过根本没有混沌。

常见混沌工具

  • Chaos Monkey – 最早的混沌工具
  • LitmusChaos – 原生 Kubernetes 开源工具
  • Gremlin – 可控的企业级混沌平台
  • AWS FIS – 原生 AWS 故障注入服务

工具本身不等同于混沌工程;思维方式才是关键。

示例场景(Kubernetes + Spring Boot)

  • 技术栈: Java Spring Boot 微服务、Kubernetes(EKS)、已启用 HPA、Redis 缓存、PostgreSQL 数据库
  • 混沌操作: 在高峰流量期间杀掉 50 % 的 pod

观察到的故障:

  • 连接池耗尽
  • 数据库被猛烈重试
  • 延迟冲破 SLA
  • 没有断路器,重试过于激进,超时配置不佳

新增的缓解措施:

  • 引入 Resilience4j(断路器、调优重试与超时)
  • 改进就绪探针

结果: 系统经受住了混沌——证明负责任地使用混沌工程是有效的。

混沌工程的原则

  • 假设驱动 – 以对稳态的明确假设为起点。
  • 可测量 – 在实验前、期间和之后收集指标。
  • 可回滚 – 确保能够快速恢复。
  • 有目的的随机性 – 避免仅仅是“随意破坏”,那只是糟糕的运维。

你需要完善的监控、便捷的回滚、错误预算,以及懂系统的值班团队。没有可观测性,混沌只会产生噪音。

好处

  • 减少生产宕机
  • 加快事故响应
  • 部署更安全
  • 系统设计更优
  • 值班工程师更有信心

你不再是“希望”系统能正常工作,而是知道它能。

入门指南

  1. 选择低风险目标(例如非关键微服务)。
  2. 定义稳态指标(成功率、延迟、错误预算)。
  3. 运行小规模实验(杀掉一个 pod、添加延迟)。
  4. 观察、学习、迭代

逐步扩大范围,并在低流量窗口期将实验迁移到生产。

结束语

如果你今天在生产系统里杀掉了一个东西,首先会崩溃的是什么?

在评论区留下你的想法、战场故事或疑问——让我们在值班铃再次响起之前相互学习。

Back to Blog

相关文章

阅读更多 »