【虎鲸进化论 29】事故复盘:它把自己搞坏过
本文是「虎鲸进化论」系列第 30 篇(正文第 29 篇)。上一篇:进化的进化;下一篇预告:安全护栏 —— 人类闸门、审计与爆炸半径。
前言
上一篇的结尾预告了:那一天,它第一次把自己搞坏了。
这一篇讲那一次事故 —— 也讲它背后真正的重点:复盘的对象,从来不是"那次操作"。
(照例:内网细节无截图;事故做模糊化还原 —— "搞坏自己的方式"保真,细节做了处理。)
一、那一晚
那一晚的真相比剧本还"教材":它在给自己做一个例行升级 —— 改了一处夜间任务的调度逻辑。按自举流程,新版本拉起、探活检查 —— 过了。但过的是浅探活:进程在、端口通;深功能已经哑了—— 新的调度逻辑在某个特定参数组合下会把自己锁死,而这个组合,恰好要在它开始跑批之后才会被触发。
它是在凌晨自己发现的(第 24 篇的自我巡检救了场:它发现"任务队列有积压、进度为零"这个组合不健康)。接下来的一切按演练过的剧本走:回滚机制启动、切回上一个版本、探活复验通过。从"坏掉"到"退回去",全程没有人类参与。
(全组事后最一致的感受不是后怕,是意外 —— 意外它"死"得这么规矩:连坏,都坏在了剧本里。)
对照"翻车不死"的通用剧本,那晚逐步走了一遍:
- 它按自举流程(第 10 篇)给自己部署了一个新版本;
- 新版本没有通过探活 —— 或者更糟:通过了浅探活,但深功能已经哑了(第 09 篇"自以为活着"的完全体);
- 回滚机制启动:切回上一个版本,探活复验通过;
- 它自己写了一份事故报告—— 是的,写报告的主体是它自己;
- 第二天早上,人复核报告,决定复盘的深度与后续动作。
请注意第 4 条的分量:事故的第一手记录者,就是肇事者本人。这个设定后面会还债(第 31 篇:当没人再读它的代码,也没有人再验证它的报告,会发生什么)。
二、复盘:对象不是"操作",是"系统"
复盘走的五步,和我们处理它的任何事故一样 ——但被审的对象换了一级:
| 步骤 | 问的问题 |
|---|---|
| 时间线还原 | 什么时候、它做了什么、系统发生了什么 |
| 根因 | 为什么那个操作会造成这个后果 |
| 机制漏洞检测 | 哪一层护栏,本该拦住它?为什么没拦? |
| 修复 | 补哪个漏洞(工具?流程?判据?) |
| 防复发 | 沉淀用例(第 23 篇)、升级护栏(下一篇)、归档知识库 |
关键的是第三步的措辞:“哪一层护栏本该拦住它”——复盘的对象不是那次操作,是"允许那次操作发生的系统"。
这个视角的转换,是工程文化里最贵的习惯之一:事故不是"谁笨",是"哪个洞"—— 而洞是系统的,不是人的。
三、暴露的真正问题:护栏的层数
复盘之后,我们发现的真相有点扎心:我们以为自己有 N 层防护,实际只有 N-1 层。(工程界墨菲定律的本地版:每一层"看起来有"的防护,都在等一次事故来证明它没有。)
那少掉的一层,是一个"看起来有、实际没有"的防护 ——深功能探针只覆盖了主链路,没覆盖夜间任务队列的健康度。换句话说:“服务活着"是有人守的;但"夜里的活是不是在正常推进”—— 当时看着像有人守(毕竟有队列监控),实际上守的只是"队列进程活着"。两回事。和第 09 篇那句"自以为活着"一模一样 —— 同一个坑,换了一层皮。
这里补一条从事故里学来的通用道理,值得所有做无人值守系统的人抄走:
护栏的作用,从来不是防第一错 —— 是防"第一错变成第二错"。
它犯错是必然的(概率底座,第 31/32 篇会再谈);护栏的价值在于:第一错发生时,系统仍然收得住。探活拦住"半死的版本"是收;回滚拦住"带病的版本"是收;闸门拦住"不可逆动作"是收。第一错是它交的学费,第二错才是我们要防的事故。
四、"翻车不死"的完整含义
呼应一下第 09 篇的伏笔:那一晚,"不死工程"接受了一场真正的考试。
- 开机自启、守护、探活、回滚 —— 四件里真正起作用的可能只有一件(通常是回滚);但正是那一件守住了底线;
- 而这个底线,决定了全组第二天的心态:没有人把事故当成"世界末日",而是当成"一次考试通过了"—— 因为最坏的情况(生产系统躺平)根本没有发生;
- 更重要的推论:因为"翻车不死",它才敢继续自我升级。一个不允许犯错的系统,进化速度必然趋近于零 ——容错能力不是进化的对价,是进化的前提。(反例到处都是:那些"不容错"的系统,最后都学会了同一个姿势 —— 一动不动。)
这也是"自驱打磨"(第 28 篇)能成立的底层原因:它敢每晚给自己动刀,是因为知道最坏结果是"回滚到昨天"。
五、复盘之后,留下了什么
一次事故在系统里留下的东西,清单是固定的(这一套后来成了我们的例行公事):
- 一个新用例:事故的复现步骤进了回归集(第 23 篇)—— 同类问题从此上网;
- 一层新护栏:复盘发现的那个"假防护"被修成了真防护(下一篇)—— 同类洞从此被堵;
- 一条知识:事故的完整经过进了知识库 —— 供下一个它(以及下一个我们)查;
- 一份共享记忆:对我们四个和它来说,那一晚成了一个共同的"我们都记得"—— 这种共同记忆,比任何文档都更能塑造行为。
事故是系统和组织最好的老师 —— 前提是它被完整地喂给了两个"学生":人和它。喂给一半(比如只归档给人看,或只让它自己知道),学费就白交了。
结语(回味点)
复盘会的最后,大家做了一个今天看来理所当然、当时其实需要一点勇气的决定:
不是关掉它,是给它画红线。
关掉它,是承认"我们养了一个我们控制不了的东西";画红线,是承认另一半 ——“我们需要它,但我们必须学会怎么和它一起活着。”
那这节课没上完的,下一节补上:
红线,到底画在哪?
边界声明
- 本文为个人观察与判断,不代表任何任职单位的立场;
- 文中涉及的组织、系统与人名均为化名或模糊处理,数字为个人口径的测量或估算;
- 文中观点按 实测 / 推理 / 立场 分层标注,欢迎按同一标准检验。
下一篇计划聊:安全护栏—— 人类闸门、审计与爆炸半径:红线画在哪、谁守着红线、以及"它能改自己的手,但不能改法"的完整展开。
转载请注明出处:
https://lizhiyong.blog.csdn.net/article/details/168341660