专业书籍精读 · Chaos Engineering · 第 9 章
Chaos Engineering: System Resiliency in Practice · Ch 9 · Creating Foresight · 2020
你在手机上点外卖,几秒后显示「下单成功」——背后是几十个程序在互相打电话。负责这些程序的工程师,每个人只熟悉其中一小块。这一章问的是:怎么在出事之前,就发现「大家以为的系统」和「真实的系统」不一样?
前几章讲的「混沌工程」,是故意弄坏一点东西,看系统扛不扛得住。这一章说:真正最值钱的,常常不是弄坏的那一刻,而是动手之前大家坐下来聊的那一个小时。
一家人自驾出远门。出发前爸爸说「走高速,三小时到」,妈妈说「高速那段在修路,得绕」,孩子问「半路没油了怎么办?」——没人答得上来。
车还没开,三件事已经露出来了:两个人脑子里的地图不一样;有一个问题谁都没想过。在家里发现,比在半路发现便宜得多。
工程团队以前主要靠「事后复盘」学习:出了事,大家坐下来回顾。但事后回看,一切都显得「早该想到」,于是很容易变成找谁犯了错;而且学费已经交了——用户已经受了影响。
另一种做法是直接动手弄坏东西看结果。可如果没人事先说清楚「我们预期会发生什么」,结果出来了也不知道算好还是算坏。
好处是很多问题在动手之前就被挖出来了——比如发现某个警报根本没人会收到,那不用弄坏任何东西,先去修就是。团队也从「出事后追责」慢慢变成「出事前一起想」。
一句诚实的代价:这种对话很吃主持人的功力,问得不好就会变成走过场,或者变成资深的人一个人在讲。
混沌工程不只是「弄坏东西」:动手之前,把每个人脑子里对系统的想象摆到桌面上对一遍——分歧和答不上来的地方,就是下一次事故最可能藏身的地方。
想看具体怎么开这场设计会、怎么问、怎么权衡? → 切到精读版
你以为混沌实验的价值在「注入故障那一刻看到了什么」,其实大半价值发生在注入之前:把一群工程师召集起来设计实验,逼每个人说出自己对系统的预期——分歧与答不上来的地方,就是心智模型的盲区。本章把混沌工程从「事后学习」的工具,重新定位为制造前瞻(foresight)的工具:在事故发生之前,就去想象它。
全书第 9 章,Part III「人的因素」的第一篇,作者 Andy Fleener。Part II 五家公司讲的是「怎么跑实验」;从这一章起,视角从机器转向人脑里的那张图,下接 Ch10 人性化的混沌、Ch11 人在回路。标题与韧性工程学者 David Woods 研究哥伦比亚号失事的一篇文章同名,取的是同一个意思:安全来自事前想象,而非事后归因。现实里它对着任何「事故复盘做了不少、事故却还在重复」的团队。
先摆一个典型场景:一个下单服务依赖缓存、数据库、支付网关和消息队列,四五个团队各管一块,每周上线几十次。出了事,复盘会上大家才第一次把各自的理解拼到一起——「原来连接池满了以后会一直重试」「原来那个告警早就没人订阅了」。
这种学习方式有两个结构性问题。一是太贵:每条知识都是用一次真实事故换来的,用户已经付了学费。二是被后见污染:知道了结局,人会不自觉地把一连串当时模糊的信号排成一条「明显的因果链」,然后问「为什么当时没看到」——复盘滑向追责,人们开始少说话。
混沌实验本来可以把学习挪到事故之前。但很多团队把它当成「装个工具、随机关机器」:没人事先说清预期,结果出来只能说「好像没啥事」,学不到东西;或者摇到了真事故,却发现原本就没人能说清楚系统会怎样。
所以这章的问题是:怎么用混沌工程主动制造前瞻——在事故发生之前,就把工程师心智模型里的分歧与盲区挖出来?
本章把一次混沌实验拆成之前(设计)、之中(注入与观测)、之后(分析与学习)三段。工具厂商和大多数讨论都集中在「之中」:怎么注入、怎么控制爆炸半径、怎么一键中止。Fleener 的主张是:「之前」这一段本身就能产出大量洞见,它决定了「之中」看什么、「之后」能学到什么。
直觉很简单:注入只是一个按钮,而要按下它,一群人得先回答「我们预期会发生什么」。这个问题一旦被认真问出来,很多答案在按钮按下之前就已经出现了——有时是发现一个从没配好的告警,有时是两个资深工程师对同一条路径给出相反的预期。
本章借用了韧性工程(resilience engineering)学者 Erik Hollnagel 的框架:一个系统要表现出韧性,需要四种能力——响应(出事时能处置)、监控(知道该盯什么)、学习(从经验里改进)、预见(想象未来可能发生什么)。
传统的可靠性工作大多补在前三项:告警补监控、值班与预案补响应、复盘补学习。预见是最难练的一项,因为它要求人去想一件还没发生的事。混沌实验的设计环节恰好给了一个结构化的练习场:「如果这个依赖慢了 2 秒,会怎样?」——这就是在人为地制造一次「事前回顾」。
Part I 已经立下前提:复杂系统大到没有任何一个人装得下。每个工程师脑子里都有一个局部的模型——应用工程师知道重试逻辑,数据库工程师知道连接上限,平台工程师知道节点怎么被调度——而且这些模型彼此不同、各自过时。
设计会的作用,是把这些模型放到同一张桌子上。它能挖出两类东西:
本章最可操作的部分,是怎么组织实验前的这场讨论。核心角色是主持人:主持人不是来给答案的,而是来提问、追问、把每个人的说法记下来。好主持人往往对这个系统不那么熟——「外行」的问题更容易戳到大家默认为显然、其实没人验证过的地方。
讨论围绕四个议题展开,大致按这个顺序:
提问的手艺决定这场会的质量。好的问题是开放的、描述性的:「你觉得会先发生什么?」「你会怎么发现?」「上次类似情况是怎样的?」;坏的问题是封闭的或带评判的:「这应该没问题吧?」「为什么没加熔断?」——前者打开模型,后者让人开始辩护。
实验跑完,回到设计会上写下的假设逐条对照:哪些预期成立,哪些被推翻,谁的模型需要更新。被推翻的假设不是谁的失败,而是一次不用付事故学费的学习。把这些结论写进规程、告警和架构改动里,再进入下一轮设计——每转一圈,团队对系统的集体想象就离真实更近一点。
第一张表:团队获取「系统会怎样失效」这类知识的几种途径。
| 途径 | 何时学到 | 挖出什么 | 主要偏差 | 代价 |
|---|---|---|---|---|
| 事故复盘 | 事后 | 真实发生的故障链 | 后见偏差,易滑向追责 | 用户已付学费 |
| 直接注入、不设计 | 事中 | 「好像没事」或一次意外事故 | 没有预期可对照 | 学得少,风险不受控 |
| 纸上推演(tabletop) | 事前 | 流程与沟通的缺口 | 停留在想象,无法验证 | 便宜,但结论没被检验 |
| 设计会 + 实验 | 事前 + 事中 | 模型分歧、盲区,再用实验验证 | 依赖主持人,易被资深者带偏 | 每次数小时、多人参与 |
设计会的独特之处在于把「想象」和「验证」接在一起:纸上推演只有前者,直接注入只有后者。
第二张表:主持人从哪来。
| 人选 | 好处 | 代价 |
|---|---|---|
| 团队内资深工程师 | 懂系统,能当场判断 | 容易替大家回答;自己的模型被当成标准答案 |
| 相邻团队的工程师 | 懂技术但不熟这块,问题够「外行」 | 需要提前补背景 |
| 专职的韧性 / 可靠性团队 | 提问与记录的手艺稳定,可跨团队积累 | 人手有限,难以覆盖所有团队 |
落到具体选择:
三句能直接带进评审的话。一:混沌工程的产出是知识,不是故障;而知识最大的一份在实验之前。二:分歧点和答不上来的问题,是实验选题的最好指针。三:复盘是在付过学费之后学习,设计会是在付学费之前学习。
面试被问「你们怎么做混沌工程」:答「我们用某某工具每周随机关实例」是一个层级;答「每次实验前开一场设计会,先对运行规程、定范围、各自写假设,把分歧点挑出来做实验,跑完对照假设更新规程」是另一个层级——后者说明你理解混沌工程针对的是人对系统的理解,而不只是系统本身。
大厂实证
① 核心命题:混沌实验的大半价值发生在注入之前——设计实验时,逼每个人说出对系统的预期,就是在制造前瞻。
② 要解决的痛:靠事故复盘学习太贵,且被后见偏差污染;不设计的随机注入又学不到东西。
③ 框架:Hollnagel 的韧性四能力——响应、监控、学习、预见;混沌设计会专门练最难的「预见」。
④ 心智模型:每人只摸到大象一块,模型互相矛盾且过时;设计会挖出分歧(最值得实验)和盲区(往往不用实验就能先修)。
⑤ 四个议题:理解运行规程(想象的工作 vs 实际的工作)→ 讨论范围(顺带定爆炸半径)→ 形成可证伪的假设(先各自写)→ 选工具、打招呼。
⑥ 主持人:负责提问不负责答案,「外行」视角更能戳破默认;问「怎么」不问「为什么」。
⑦ 选题判据:全员一致的实验信息量低,分歧点和答不上来的问题才是好题。
⑧ 易错:开成审批会、资深者先开口、不记事前预期;前瞻不是预测,想不到的组合仍需其他手段补。