9.6

View in English

9.6 混沌工程与弹性测试

概述与动机

混沌工程是一种有纪律的实践,通过在系统上运行实验来建立对其在生产环境中承受动荡条件能力的信心。这个名字听起来很鲁莽,而这正是首先要打破的误解。混沌工程不是随机破坏事物并寄希望于从中学到什么。恰恰相反:它是一种受控的、由假设驱动的方法,用来注入真实的故障,以便你能在用户之前发现系统的弱点。你已经知道你的系统会遇到故障,因为每一个真实系统都会遇到故障。唯一的问题是,你是在周二下午、准备好回滚方案的情况下迎接这些故障,还是在凌晨 3 点、业务最繁忙的时段,在毫无头绪的情况下迎接它们。

对于大型团队而言,这一点尤为重要,因为复杂性早已超出了任何人凭检查就能推理清楚的能力范围。一个现代服务是由数十甚至数百个组件组成的网络,每个组件都有自己的超时、重试、缓存和故障模式,而它们之间的相互作用会产生涌现行为,这是任何架构图都无法预测的。你可以评审代码、画出方框图,却仍然会在一个缓慢的依赖项触发重试风暴、拖垮三跳之外的另一个服务时措手不及。混沌工程就是你用来实证地探查这些相互作用的方法,这样你的弹性就是你已经验证过的东西,而不是你所假设的东西。

企业和政府环境提高了风险,也在日益提高相应的强制要求。金融监管机构现在要求企业针对严重但合理的场景测试运营弹性,并证明它们能够在中断期间维持关键服务的运行。政府机构会开展业务连续性演练,以确保基本公共服务能在停机、灾难和网络攻击中存续下来。在这两种情境下,“我们认为它能撑住”都不是能对审计员或公民交代的答案。混沌工程为你提供证据。本章建立在站点可靠性工程(第 9.1 章)以及第 3.5 章弹性模式的基础之上,并与事件管理(第 9.3 章)和灾难恢复(第 9.5 章)紧密相连。

关键原则

  • 建立信心,而非制造混乱。 目标是经过验证的弹性,而不是场面。每一次实验都回答一个关于系统在压力下如何表现的具体问题。
  • 先定义稳态。 如果没有清晰、可度量的”健康”定义,你就无法检测出问题。
  • 形成假设。 在注入故障之前,先陈述你预期会发生什么。意外是一种发现;没有意外同样也是一种发现。
  • 最小化并控制爆炸半径。 从小处着手,保护真实用户,只在信心增长时才扩大范围。
  • 谨慎地优先选择生产环境。 故障在真实流量、真实数据和真实规模下的表现是不同的。要先赢得在那里测试的资格。
  • 朝着持续验证自动化迈进。 一个修复过一次的弱点可能会回归。只有持续测试的弹性才能保持真实可靠。
  • 失败是老师,不是判决。 发现的问题用来改进系统,绝不能作为责怪运行实验之人的理由。

建议

在注入任何一个故障之前,先建立好前提条件

混沌工程对成熟的系统是一种力量倍增器,对不成熟的系统则是一种负债。在开始之前,你需要具备三样东西。第一,可观测性,也就是能让你从外部看清系统正在做什么的指标、日志和追踪,因为一个你无法观测的实验什么也教不了你。第二,服务水平目标,或等效的稳态健康定义(第 9.1 章),这样你就能实时区分一次成功的实验和一次有害的实验。第三,快速且可信的回滚或中止路径,这样一旦实验威胁到真实用户,你就能在数秒内停止它并恢复正常服务。如果你无法度量你的系统、定义它的健康状态,也无法在它濒临崩溃时把它拉回来,那就先不要运行混沌实验。先建立这些能力。无论如何它们都是值得投入的。

定义稳态并形成真正的假设

每一次实验都从用可度量的方式写下”正常”是什么样子开始:请求成功率高于 99.9%,结账延迟在第 95 百分位低于 400 毫秒,队列深度低于某个阈值。这就是你的稳态定义,它应该反映用户可见的健康状况,而不是内部管道的状态。然后用平实的语言陈述一个假设:“如果我们给推荐服务增加 300 毫秒的延迟,商品页面仍然能在其延迟预算内渲染完成,因为该页面把推荐视为可选项,并在 200 毫秒后超时。“现在你有了一个可证伪的主张。当你运行实验时,会发生两种好结果中的一种:要么系统表现如预期,你的信心得到了印证;要么并非如此,而你以低成本、按你自己的节奏、在工程师的注视下,发现了一个真实的弱点。

注入真实的故障,而非随意的故障

你引入的故障应当反映系统实际经历的故障。故障注入是刻意引入错误以测试系统如何响应的做法,它为你提供了一份取材于真实生产事件的菜单。注入延迟,以模拟缓慢的依赖项或饱和的网络链路。注入错误,返回 HTTP 500 或拒绝连接,以模拟一个失败的下游服务。注入资源耗尽,消耗 CPU、内存、磁盘或文件描述符,看看系统在压力下如何降级。注入依赖故障,使整个数据库、缓存、队列或第三方 API 变得不可达。在分布式系统中,组件运行在不同的机器上,通过不可靠的网络通信,这些正是主导真实停机事件的故障类型。延迟和部分故障,而非干净利落的崩溃,才是实践中真正拖垮系统的元凶,所以要把你的实验重心放在那片混乱的中间地带。

验证你的弹性机制是否真的有效

这正是混沌工程发挥价值的地方。你的系统中充满了本应保护你的机制:阻止调用方无限等待的超时、掩盖瞬时故障的重试、阻止持续冲击一个失败依赖项的断路器,以及在主节点宕机时切换到备用节点的故障转移。这些模式在第 3.5 章有所介绍,是可控问题与级联式停机之间的分水岭。问题在于,它们很少在其本该应对的条件下被真正测试过。一个设置为 30 秒的超时,在调用方自身的截止时间只有 2 秒时毫无意义。一个没有退避机制的重试会把一个正在挣扎的服务变成惊群效应的牺牲品。一个从未被触发过的断路器可能配置有误,永远不会跳闸,或者反而频繁跳闸。混沌实验正是用来确认,当它们所防范的故障真正到来时,这些机制中的每一个是否都能按设计运行。在实验证明相反之前,假设每一个未经测试的安全机制都是坏的。

在实现自动化之前,先从游戏日开始

不要一开始就用一个持续注入故障的自动化平台。从游戏日开始:这是一场有计划、由人主导的演练,团队聚在一起,选定一个场景,在受控环境中注入一个故障,并共同观察结果。在此之前,甚至可以先做一次桌面演练,即不触碰系统、仅在白板上推演场景,这几乎不承担任何风险,却能暴露操作手册、告警和归属权方面的差距。游戏日是你的入门坡道。它们锻炼了形成假设、控制爆炸半径以及在压力下解读系统的能力,也建立起你在获准于生产环境中运行实验之前所需要的、来自领导层和相邻团队的信任。它们还能直接强化事件响应能力,因为所用的技能与你的待命工程师在真实事件中所用的技能是一样的(第 9.3 章)。先在预发布环境中开展你的首批游戏日,然后在业务清淡时段以较小的爆炸半径在生产环境中开展,再逐步扩大范围。

刻意控制爆炸半径

最重要的安全实践是限制每次实验的潜在危害。从能教给你一些东西的最小范围开始:一个实例、百分之一的流量、一个非关键依赖项、一个可用区。在开始之前先定义中止条件,将它们与你的稳态指标关联起来,并让停止实验成为任何在场观察者都能触发的单一动作。优先在团队保持警觉和有人值守的工作时段进行实验,而不是在无人值守的夜间,因为那样一个意外就会变成一次事件。只有在较小规模的实验已顺利完成、你的信心确实提高之后,才扩大爆炸半径。这种控制的纪律,正是混沌工程与你自己造成的停机事件之间的分界线。

朝着持续、自动化的弹性验证迈进

偶尔的游戏日能发现弱点,但系统每天都在变化,上一季度的修复可能悄悄地退化。成熟的终局状态是持续验证:一组经过精心挑选的弹性实验,在流水线中或按计划自动运行,这样超时、重试策略或故障转移路径中的一次回归就能在数天之内被发现,而不是要等到下一次真实的停机事件才被发现。这正是 Netflix 的 Chaos Monkey 等工具赢得声誉之处,它在生产环境中随机终止实例,迫使工程师构建能够容忍实例丢失的服务。只自动化那些你已经通过手动运行理解和信任的实验。在不成熟的系统之上运行持续混沌,产生的是事件而不是信心。

将实验与灾难恢复及事件学习联系起来

混沌工程并非孤立存在。那些更大、更罕见的场景,比如丢失整个区域、数据库故障转移、从备份恢复,属于灾难恢复测试的范畴(第 9.5 章),而游戏日往往是演练这些方案的最佳载体,胜过任由它们作为从未测试过的文档烂在抽屉里。另一方面,每一个揭示出弱点的实验都应该汇入与真实事件(第 9.3 章)相同的学习闭环:一份无责的书面总结、一项被跟踪的修复,以及一次用来确认修复是否成立的后续实验。当混沌发现、灾难恢复演练和事件复盘全部汇入同一个弹性工作积压列表时,你获得的是复合回报,而不是零散的一次性演练。

权衡:优点与缺点

决策优点缺点
在生产环境中测试真实流量、数据和规模;发现结果真实可信若控制失效则危及用户;需要较高成熟度
仅在预发布环境中测试安全、风险低、易于起步遗漏真实场景中的行为;可能产生虚假的信心
人工游戏日建立技能和信任;工具成本低频率低;发现的问题可能在无人察觉时回归
持续自动化混沌快速捕获回归;可扩展需要先具备成熟的工具和可观测性
较大的爆炸半径揭示大型系统性弱点风险高;一个失误就会变成事件
较小的爆炸半径安全且可控可能遗漏涌现的跨服务故障

核心张力在于真实性与安全性之间。你最想要的发现来自生产环境,因为那是你的系统面对真实流量、真实数据和真实规模的唯一场所,然而生产环境恰恰也是一次失败的实验会伤害用户的地方。解决办法不是选择其中一方,而是逐步赢得进入生产环境的资格:先证明前提条件已具备,在预发布环境中演练,然后在生产环境中运行规模小、控制严密、中止条件与实时指标相关联的实验,只在证据积累后才扩大范围。另一种反复出现的张力,即人工与自动化之争,也随着时间以同样的方式化解。先靠人工建立理解和信任,然后把你已经开始依赖的实验自动化,这样你曾经验证过的弹性就能保持被验证的状态。

与团队讨论的问题

  1. 我们真的准备好运行混沌实验了吗?我们怎么知道? 因为听起来很高深,人们很容易就想开始注入故障,但在一个不可观测、没有清晰健康定义、也没有快速回滚手段的系统上做混沌工程,只是自找停机。把诚实的证据带到这场讨论中来:你能实时看到请求成功率和延迟吗?你们对稳态有没有达成一致的定义?你能否在数秒内中止一个实验并恢复正常?对于一个大型团队,答案往往因服务而异,所以有用的产出是一道服务必须先跨过才有资格接受实验的准入门槛。在受监管的环境中,这道准入门槛同时也是你可以向审计员展示的一项控制措施。如果诚实的答案是你们还没准备好,那么本季度你能做的最有价值的混沌工作,就是建立让你准备好的可观测性和回滚能力。

  2. 我们的爆炸半径政策是什么?谁有权停止一个实验? 每一次混沌实验都会给真实用户带来某种风险,而一个有价值的发现与一次由你造成的事件之间的区别,就在于你控制得有多严密。具体讨论清楚这些限制:多大比例的流量、多少个实例、哪些环境、一天中的什么时段,以及哪些指标阈值会自动中止运行。提前决定谁在监看每一次实验,谁掌握那个一键式的紧急开关,因为一个没有人能迅速停止的实验就不算是受控的。对于一个大型组织,正是这项政策让许多团队能够开展实验,而不会有任何一个团队意外地拖垮一个共享的依赖项。答案应该被写下来,与你的实验可能影响到的团队达成一致,并被当作在生产环境中运行任何东西的前提条件来对待。

  3. 我们认为保护我们的是哪些弹性机制?我们真的测试过它们吗? 大多数系统里充满了超时、重试、断路器、缓存和故障转移路径,它们被配置一次之后,就再也没有在其本该应对的故障下被真正触发过。列出你所依赖的这些机制,然后针对每一个都问一句:它上一次在真实注入的故障下被验证有效是什么时候。与此相竞争的考量是时间:验证每一个机制都要耗费工程精力,而功能上线的截止日期永远存在。用反例来回应这种质疑,也就是过去某次停机事件本可以被一个真正有效的断路器或一个正确的超时所控制住的代价。答案应该把一份令人安心的”假定保护措施”清单,转变为一份按优先级排序的实验待办列表,从那些一旦失效伤害最大的机制开始。

  4. 在生产环境而不是预发布环境中运行实验之前,必须先具备什么条件?今天有哪些服务已经赢得了这个资格? 你最想要的发现来自生产环境,因为那是你的系统面对真实流量、真实数据和真实规模的唯一场所,然而生产环境也是唯一一个失败实验会伤害真实用户的地方。对于一个大型团队,诚实的现实是不同服务处于不同的准备程度,所以一刀切的”生产环境禁止混沌”规则会浪费掉你最好的学习机会,而一刀切的”全部允许”则会招致自找的停机。带上每个服务的证据:其可观测性的质量、稳态是否已被定义并可告警、回滚有多快,以及能够证明它有资格升级的、干净的预发布环境实验记录。在企业和政府环境中,把生产环境准入关口与一项有据可查的控制措施绑定起来,写明谁批准这次晋级、哪些中止条件与实时指标相关联,这样审计员看到的就是一个经过深思熟虑、有证据支撑的决定,而不是一个团队拿真实用户即兴发挥。

  5. 当一次混沌实验揭示出一个弱点时,这个发现该去往何处?我们如何防止它被搁置腐烂? 一个只发现弱点却从不修复的项目,比没有这个项目还要糟糕,因为它消耗精力、侵蚀信任,并让人们以为实验不过是场表演。与之相竞争的压力始终来自功能路线图:在预防的那次停机真正到来之前,一项弹性修复很少会像下一个发布那样让人感到紧迫。把你当前弹性待办列表的状态带到讨论中来:有多少混沌发现仍未解决,最老的一项有多久了,以及来自实验、灾难恢复演练和事件复盘的发现,是汇入同一个共享队列,还是分散在各个团队之中。就谁负责每一项修复、谁来运行确认修复是否成立的后续实验达成一致。对于一个大型或受监管的组织,指明按固定节奏评审这份待办列表、并有权将一项弹性修复的优先级排在某个功能之前的那个论坛,因为一个没有人对其关闭负责的发现,只是一项你记录下来却并未消除的风险。

  6. 我们是否已经准备好把某些实验自动化为持续验证?具体是哪些? 偶尔的游戏日能发现弱点,但系统每天都在变化,上一季度的修复可能悄悄退化,所以成熟的终局状态是一组经过精心挑选、自动运行的实验,能在数天之内捕获回归。危险在于自动化得太早:在一个可观测性薄弱的不成熟系统之上叠加持续混沌,产生事件的速度会超过产生洞见的速度。带上那些你已经手动运行足够多次、足以完全信任的实验清单,带上将在无人值守时管控它们的爆炸半径控制和中止条件,以及能在凌晨 3 点无人监看时捕获自动运行出问题的监控手段。对于大型企业或公共机构,权衡一下无人值守的故障注入会招致的额外审查:变更管理签核、每次自动运行必须留下的审计轨迹,以及一次预定实验恰好与一次真实事件重合时明确的问责归属。只自动化你已经理解的实验,其余的在赢得同等信任之前保持人工方式。

行业视角

创业公司。 速度和生存压倒一切,所以不要在混沌平台上花一分钱。在预发布环境中针对那个一旦失效就真的会要命的依赖项()通常是支付、鉴权或主数据存储()开展一次九十分钟的游戏日。用一个简陋的代理或直接杀掉进程来注入故障,观察发生了什么,修复缺失的超时或回退逻辑,然后继续前进。整件事的意义在于以低成本先于客户发现那个显而易见的自找停机,而不是去建立一套你根本养不起人的规范化实践。

小型企业。 由于没有可靠性专员、预算又紧,应把弹性测试当作一项定期的、刻意为之的演练,而不是一个需要专人配置的项目。依靠你的云服务商或托管工具已经内置的故障注入功能,而不是购买专门的平台,并把实验重点放在客户会注意到的那几个依赖项上。把它当作一种保险来看待:花一个下午确认你的备份能恢复、你的结账流程能优雅降级,远比证明它们做不到的那次停机便宜得多。

企业。 问题在于要协调众多团队围绕大规模的共享依赖项开展工作,所以要把每个团队在生产环境中运行实验之前必须跨过的准入门槛、爆炸半径政策和中止条件接线标准化。把混沌发现、灾难恢复演练和事件复盘汇入同一个有明确责任归属的弹性待办列表,用季度游戏日加上一组经过精心挑选的自动化实验,以证据的方式满足运营弹性方面的期望。管控谁可以影响一个共享服务,这样才不会有任何一个团队的实验拖垮其他团队所依赖的基础设施。

政府。 采购规则、透明度和公共问责塑造了这项工作。业务连续性方面的强制要求往往本来就需要定期演练,所以要把它们运行成能产生真实发现的现场游戏日,而不是一份没人翻阅的活页夹,并为每一次实验、它的爆炸半径及其结果保留审计轨迹。在采购故障注入工具时,要求它符合安全和数据处理规则,并把面向公民的服务上的生产环境实验,保留给受严格控制、经过批准的窗口期。混沌项目产生的证据,正是监督机构或审计员所期望看到的东西。

示例

创业公司。 一家十五人规模的创业公司在少数几个服务上运行一个 Web 应用,并依赖一个第三方支付 API。没有人有时间搭建混沌平台,于是团队在预发布环境中开展了一次九十分钟的游戏日。他们形成了一个假设:如果支付 API 开始返回错误,结账流程应该显示清晰的重试提示,并将订单排队,而不是崩溃。他们用一个简单的代理注入 500 响应,结果发现前端会无限期挂起,因为客户端调用没有设置超时。他们添加了超时和一个友好的回退方案,重新运行实验以确认修复有效,并在共享文档中写下了一段两段式的说明。总成本:一个下午,加上一个在客户遇到之前就被抓住的非常真实的漏洞。

企业。 一家全球性银行必须向监管机构证明其针对严重但合理场景的运营弹性。它的可靠性团队运行一套季度游戏日加上一组生产环境自动化实验的项目。其中一个场景是在低流量时段将主交易数据库故障转移到备用节点,爆炸半径受到严格控制,中止条件与交易成功率相关联。第一次运行揭示出,一个下游对账服务的重试策略没有退避机制,导致负载激增,使恢复时间大幅超出灾难恢复方案(第 9.5 章)中的恢复时间目标。这一发现被纳入与事件复盘相同的待办列表,重试策略被修复为带指数退避,一次后续实验确认故障转移现在能在目标时间内完成。整场演练成为了提供给监管机构的证据。

政府。 一家运营面向公民的福利门户网站的国家机构,被要求在中断期间维持业务连续性。这家机构没有把连续性方案当作一份没人翻阅的活页夹,而是把年度连续性演练运行成一次现场游戏日。团队模拟了主数据中心的丢失,并演练了向次要站点的故障转移,同时另外向一个身份验证依赖项注入延迟,观察门户网站能否优雅降级。他们发现,一个未经测试的监控盲区,使值班团队对身份验证服务变慢一事一无所知,导致告警延迟触发。该机构弥补了这一可观测性缺口,更新了操作手册,并把同样的演练安排到下一年,把一项合规要求变成了一项针对关键公共服务的、真正经过测试的弹性。

商业理由:动机、投资回报率与总拥有成本

混沌工程的回报,来自那些从未发生过的停机事件。对一个大型服务而言,一次重大停机的成本可能从数万美元到数百万美元不等,涵盖收入损失、监管处罚、修复人力,以及在服务恢复很久之后依然挥之不去的声誉损害。混沌实验把那些不可预测、代价高昂的意外,转化为廉价的、按计划进行的发现,你可以按自己的节奏修复,有工程师在场,随时准备好回滚。在一次受控的游戏日中发现一个失效的超时,代价是一个下午。而在一次真实事件中发现它,代价是一场停机、一次全员出动的紧急应对,以及用户的信任。这笔账无论怎么算,都是游戏日更划算。

一旦前提条件到位,总拥有成本就相当有限,因为混沌工程复用的正是你本来就需要的可观测性、告警和回滚投入。真正的成本在于运行实验所需的工程时间、一些用于注入故障和控制爆炸半径的工具,以及让领导层能够接受刻意引入故障这件事所需的文化工作。最后这一点才是真正的障碍,跨过它的办法是先在预发布环境中起步,展示能够对应到资金或风险的发现,再让几次受控的生产环境实验逐步建立信任。要向领导层说明理由,可以把混沌工程定性为一种可以量化的保险:呈现近期事件的成本,指出其中哪些本可以被一次弹性实验捕获,然后提出一个从小规模起步、只在证明自身价值后才扩展的项目。在受监管和公共部门的环境中,加入合规这个角度,因为运营弹性测试和连续性演练正日益成为一项预期要求,而一个混沌项目正是你用证据而非纸面文书来满足这项预期的方式。

反模式与陷阱

  • 没有可观测性的混沌。 向一个你看不见的系统注入故障,只是带着额外步骤的瞎猜;你会造成伤害,却学不到任何东西。
  • 没有稳态定义。 如果没有一个双方认可的健康度量标准,你就无法分辨一次实验究竟是揭示了问题,还是造成了问题。
  • 没有假设。 随机破坏事物不是混沌工程,那只是披着华丽名号、却毫无发现的破坏行为。
  • 未受控的爆炸半径。 跳过小规模、安全的实验,直接对整个生产环境发起故障,会把一次测试变成一次自找的停机事件。
  • 没有中止路径。 一个你无法立即停止的实验根本不是实验,而是一个等待触发的事件。
  • 自动化得太早。 在不成熟的系统之上运行持续混沌,产生事件的速度会超过产生洞见的速度。
  • 发现的问题无人处理。 发现一个弱点却从不修复,白白浪费了这次演练,并侵蚀了整个项目的信任。
  • 在一次糟糕的实验后追究责任。 惩罚那个揭示出真实缺陷的工程师,只会确保没有人愿意再运行下一次实验。

成熟度模型

  • 第 1 级,启动: 弹性只是被假定的,而未经过测试。故障是在真实事件发生时于生产环境中才被发现的。没有游戏日,没有故障注入,往往也没有一个清晰的”健康”定义。团队只能靠一次又一次的停机来痛苦地了解自己的弱点。
  • 第 2 级,发展: 团队偶尔开展游戏日,通常在预发布环境中进行,有明确的场景和假设。少数几个关键服务定义了稳态,也具备了基本的可观测性。发现的问题会被记录下来,其中一些会被修复,但这种实践在各团队之间并不一致,依赖个别推动者,而非一套确立的方法。
  • 第 3 级,标准化: 混沌实验成为一项有文档记录、覆盖全组织的实践,具备强制执行的爆炸半径政策、中止条件,以及服务在生产环境中开展实验之前必须跨过的准入标准。实验在受控条件下于生产环境中运行,发现的问题汇入与事件复盘和灾难恢复演练共享的弹性待办列表,弹性机制是经过验证的,而不是被假定的。每个团队都遵循同一套操作手册。
  • 第 4 级,管理: 该项目被度量并依据基线数据进行管控。你追踪弹性覆盖度(哪些关键服务、哪些机制()如超时、重试、断路器和故障转移()已在真实注入的故障下得到验证,以及最近一次验证是何时)、实验揭示发现的比率、关闭一项弹性发现的平均耗时,以及一个先前已验证的机制发生回归的频率。这些指标按固定节奏被评审,生产环境的晋级以证据而非主观判断为门槛,实验则按尚未验证的机制所测得的风险来排定优先级。
  • 第 5 级,编排: 一组经过精心挑选的实验持续自动运行,能在数天之内捕获回归,且该项目会随系统及其风险状况的变化而调整。混沌工程与交付流水线、事件学习和灾难恢复测试在组织层面深度整合,使新服务默认就继承了弹性验证能力。弹性成为系统一项被持续验证的属性,领导层将该项目视为依据证据不断打磨的标准风险管理手段,而非一项特殊举措。

讨论话题

  1. 你如何决定组织中哪个服务最先赢得在生产环境中运行混沌实验的资格?在此之前必须具备什么条件?
  2. 当一次混沌实验揭示出一个严重弱点时,谁来负责修复?你如何防止这一发现在待办列表中被搁置不理?
  3. 在你所处的语境中,混沌实验、灾难恢复演练和游戏日之间的界线在哪里?这种区分对你如何规划它们真的重要吗?
  4. 你会如何说服一位持怀疑态度的高管,让他相信刻意向生产环境注入故障,比维持现状、坐等真实停机发生更安全?
  5. 你的团队下个月可以运行的、最小却最有价值的第一个实验是什么?是什么阻止了你去运行它?
  6. 针对一个负有连续性使命的面向公民的公共服务,与一个用户量很小的内部企业工具,弹性测试应该有何不同?

关键要点

  • 混沌工程是有纪律、由假设驱动的实验,用来建立对弹性的信心,而不是随机破坏。
  • 在注入任何一个故障之前,先建立可观测性、稳态定义和快速回滚能力。
  • 注入真实的故障(延迟、错误、资源耗尽、依赖故障),并用它们来验证超时、重试、断路器和故障转移是否真的有效。
  • 从桌面演练和游戏日开始,刻意控制爆炸半径,逐步赢得进入生产环境和实现自动化的资格。
  • 把实验与灾难恢复测试(第 9.5 章)和事件学习(第 9.3 章)联系起来,让发现的问题汇入同一个弹性待办列表,产生复合效应。
  • 以无责的方式对待发现的问题并加以修复;一次教训未被采纳的实验,比根本没有实验还要糟糕。

参考文献与延伸阅读

  • Casey Rosenthal, Nora Jones, Chaos Engineering: System Resiliency in Practice
  • Russ Miles, Learning Chaos Engineering: Discovering and Overcoming System Weaknesses Through Experimentation
  • Mikolaj Pawlikowski, Chaos Engineering: Crash Test Your Applications
  • Ali Basiri et al., Chaos Engineering (IEEE Software, 2016)
  • Betsy Beyer, Chris Jones, Jennifer Petoff, Niall Richard Murphy, Site Reliability Engineering: How Google Runs Production Systems
  • Michael T. Nygard, Release It! Design and Deploy Production-Ready Software
  • Principles of Chaos Engineering, principlesofchaos.org