事故复盘不是写检讨,而是让团队变强的一次机会

举报
Echo_Wish 发表于 2026/09/15 08:10:33 2026/09/15
【摘要】 事故复盘不是写检讨,而是让团队变强的一次机会

事故复盘不是写检讨,而是让团队变强的一次机会

凌晨 2 点,监控突然开始报警。

接口 P99 从 200ms 飙到 5s,错误率一路上涨。值班同学冲进群里,开始查日志、重启服务、扩容、回滚。

两个小时后,服务终于恢复。

第二天上午,大家坐在会议室里开事故复盘。

然后有人问:

“这次事故到底是谁改的?”

如果复盘最后变成了这句话,那我觉得这次事故基本算白出了。

真正成熟的运维团队,应该慢慢完成一个转变:

从“事故发生了以后怎么解释”,走向“事故发生以后组织怎么变强”。

这也是我越来越认同的一件事情:

Postmortem 的终点,不应该是一份复盘文档,而应该是一次组织学习的开始。


一、很多公司的事故复盘,其实只是“事故作文”

我见过一些非常典型的事故复盘。

标题:

《XX系统 9月15日生产事故复盘报告》

内容大概是:

事故时间: 02:13
事故恢复: 03:47
事故影响: XX用户
事故原因: 某同学发布配置错误
处理方式: 回滚
责任人: XXX
整改措施: 加强发布审核

看起来特别完整。

但是过了三个月,同样的事故又发生了。

只是这次换了个人。

为什么?

因为这种复盘回答的是:

“上一次是谁做错了?”

而不是:

“为什么一个正常工作的工程师,能够这么容易把系统搞挂?”

这两个问题看起来差不多,实际上完全不同。


二、真正应该复盘的,不是“谁犯错”,而是“系统为什么允许错误发生”

假设生产环境有这样一条命令:

kubectl delete deployment payment-service -n prod

一个新人拿到了生产权限。

凌晨三点,他本来想删除测试环境 Deployment,结果 namespace 写错了。

系统挂了。

如果你的复盘结论是:

“新人操作失误,生产操作不规范。”

那你下一步大概率会做:

加强培训
加强教育
加强审批
加强责任意识

听起来都对。

但其实没有解决核心问题。

因为真正值得问的是:

为什么一个人的一个命令,就能让生产系统直接进入不可用状态?

成熟一点的改进可能是:

生产环境禁止直接 kubectl delete
        ↓
必须通过发布平台操作
        ↓
平台识别生产环境
        ↓
高危操作二次确认
        ↓
权限最小化
        ↓
操作审计
        ↓
异常行为自动告警

这时候,事故才真正产生了价值。

因为你不是要求:

“以后大家千万别犯错。”

而是让系统变成:

“即使有人犯错,也不至于造成灾难。”

这才是工程思维。


三、Postmortem 最重要的一个词:Blameless

很多人第一次听到 Blameless Postmortem(无责复盘),会产生一个误解:

“无责复盘是不是出了事故也不用追责?”

不是。

Blameless ≠ 不承担责任。

它真正想表达的是:

复盘的时候,不要把人的错误当成分析终点。

比如:

def deploy(config):
    if config.env == "prod":
        deploy_to_production(config)

这里最大的风险是什么?

不是某个人粗心。

而是:

代码允许任何人直接部署生产

那我们真正应该修改的,是系统。

例如:

def deploy(config, operator):
    if config.env == "prod":
        if not operator.has_permission("prod_deploy"):
            raise PermissionError("没有生产发布权限")

        if not config.approved:
            raise PermissionError("生产发布未审批")

    return deploy_to_environment(config)

再进一步:

def deploy(config, operator):
    validate_config(config)

    if config.env == "prod":
        check_permission(operator)
        check_approval(config)
        check_change_window(config)
        create_audit_record(operator, config)

    return deploy_to_environment(config)

你会发现:

真正优秀的复盘,最后一定会落到系统、流程、工具和组织机制上。


四、事故不是“坏事”,重复事故才是真正的坏事

我特别喜欢一个判断事故价值的方法:

第一次事故叫问题,第二次同类事故叫管理问题。

比如第一次 Redis 把内存打爆。

大家发现:

没有内存告警
没有容量预测
没有淘汰策略
没有压测

然后补上。

半年后,又因为 Redis 内存爆了。

这时候就不能再简单说:

“又一次 Redis 内存事故。”

真正应该问的是:

为什么第一次事故留下的知识,没有进入组织?

这就涉及一个很容易被忽略的问题:

事故复盘 ≠ 组织学习

复盘只是:

发生了什么?
为什么发生?
怎么恢复?
以后怎么办?

而组织学习则是:

事故
 ↓
知识
 ↓
行动
 ↓
机制
 ↓
标准
 ↓
工具
 ↓
自动化
 ↓
组织能力

这是完全不同的层次。


五、不要只写“整改措施”,要给整改措施加上生命周期

很多 Postmortem 最大的问题,是整改项写得特别漂亮。

例如:

1. 增加监控
2. 优化发布流程
3. 加强代码审核
4. 完善应急预案

然后一个月以后:

TODO
TODO
TODO
TODO

最后谁都不知道做到什么程度了。

我更推荐把事故 Action Item 做成类似下面这种结构:

action_items = [
    {
        "problem": "数据库连接池耗尽",
        "action": "增加连接池使用率监控",
        "owner": "张三",
        "priority": "P0",
        "deadline": "2026-09-20",
        "status": "DOING",
        "verify": "模拟连接池耗尽,确认告警5分钟内触发"
    }
]

注意最后那个:

verify

非常重要。

因为:

没有验证方式的整改措施,很容易只是“写过了”。

比如:

增加数据库监控

不够。

应该变成:

数据库连接池 > 80%
    ↓
触发 Warning

数据库连接池 > 95%
    ↓
触发 Critical

模拟连接池耗尽
    ↓
确认告警
    ↓
确认通知
    ↓
确认值班人员收到

这时候,它才从一句话变成真正的工程能力。


六、事故复盘真正应该关注的是“控制点”

举个大家都熟悉的例子。

一次线上发布导致 CPU 100%。

最开始调查发现:

某次代码提交引入了死循环

如果到这里就结束了:

“开发写代码不严谨。”

那意义其实不大。

继续往下问:

第一层

为什么有死循环?

代码 Bug

第二层

为什么测试没发现?

测试场景覆盖不足

第三层

为什么测试场景覆盖不足?

没有针对大数据量做测试

第四层

为什么没有大数据量测试?

性能测试没有纳入发布门禁

第五层

为什么发布可以绕过性能测试?

CI/CD 没有强制检查

你看。

一开始是:

一个 Bug

最后变成:

CI/CD质量门禁缺失

这就是典型的 从个人错误走向系统性原因


七、真正高级的运维,不是“救火快”,而是“让火越来越少”

传统运维经常有一种英雄主义:

“这个问题只有我能解决。”

凌晨服务器挂了。

某个大佬上线。

ssh production
tail -f xxx.log
grep ERROR xxx.log
kill -9 xxx
systemctl restart xxx

然后:

“好了。”

群里:

“牛逼。”

确实牛逼。

但从组织能力角度来看,这其实不一定是好事。

因为如果:

只有 A 知道怎么处理

那么组织能力其实是:

A = 100
其他人 = 0

真正成熟之后应该变成:

A知道
 ↓
A写下来
 ↓
形成Runbook
 ↓
自动化
 ↓
新人也能执行

最终:

if service_down:
    detect()
    diagnose()
    execute_runbook()
    verify()
    record()

这时候,原来只有一个人会的“绝活”,变成了整个团队的基础能力。


八、我特别建议把事故沉淀成“可执行知识”

很多公司的 Wiki 有几十万字。

但真正出事故的时候,没人看。

为什么?

因为知识写成了:

第一章 系统介绍
第二章 架构说明
第三章 网络拓扑
第四章 数据库设计
……

半夜三点的时候,你根本没心情看。

真正有价值的运维知识应该长这样:

【现象】
接口 5xx > 10%

【第一步】
检查:
kubectl get pods

【第二步】
查看:
kubectl logs xxx

【第三步】
如果出现:
OOMKilled

【处理】
kubectl rollout restart deployment xxx

【验证】
错误率恢复 < 1%

【升级】
超过10分钟无法恢复,通知DBA

这才叫:

Runbook。

它的价值不是“记录历史”。

而是:

让下一次事故处理得更快。


九、事故还可以反过来喂给监控、测试和AI

这也是我认为未来 AIOps 特别有价值的一点。

一次事故发生:

事故
 ↓
日志
 ↓
指标
 ↓
Trace
 ↓
人工判断
 ↓
根因

如果只是写一份 Postmortem:

事故结束

就结束了。

但如果继续做:

事故
 ↓
提取特征
 ↓
形成规则
 ↓
加入监控
 ↓
加入测试
 ↓
加入知识库
 ↓
AI学习

那事故就开始产生复利。

例如以前:

数据库连接数 > 90%

没人特别关注。

发生一次事故以后发现:

连接数 > 90%
+
慢SQL增加
+
CPU > 80%
+
请求量持续上涨

是一个非常危险的组合。

那么就可以形成:

if (
    db_connections > 0.9
    and slow_sql_rate > 0.2
    and cpu_usage > 0.8
):
    alert(
        level="critical",
        message="数据库资源耗尽风险"
    )

下一次事故甚至可能还没发生,系统已经告诉你:

“这个事故正在形成。”

这就是从:

事故响应

走向:

事故预防。


十、最终要建立的是一条“事故 → 能力”的流水线

如果让我给一个真正落地的模型,我会这样设计:

                ┌──────────────┐
                │    生产事故   │
                └──────┬───────┘
                       ↓
                ┌──────────────┐
                │   快速恢复    │
                └──────┬───────┘
                       ↓
                ┌──────────────┐
                │   Postmortem │
                └──────┬───────┘
                       ↓
              ┌────────┴────────┐
              ↓                 ↓
          技术原因            系统原因
              ↓                 ↓
          修复Bug             修机制
              ↓                 ↓
          加测试              加监控
              ↓                 ↓
          加告警              自动化
              └────────┬────────┘
                       ↓
                ┌──────────────┐
                │   Runbook     │
                └──────┬───────┘
                       ↓
                ┌──────────────┐
                │   知识库      │
                └──────┬───────┘
                       ↓
                ┌──────────────┐
                │   团队培训    │
                └──────┬───────┘
                       ↓
                ┌──────────────┐
                │ 组织能力提升  │
                └──────────────┘

这才是真正意义上的:

从 Postmortem 到组织学习。


十一、最后,我越来越觉得:事故本身不是最可怕的

运维工作有一个很残酷的现实:

复杂系统一定会出事故。

你再努力,也不可能做到:

事故率 = 0

真正应该追求的可能是:

事故发生
 ↓
影响越来越小
 ↓
发现越来越快
 ↓
恢复越来越快
 ↓
重复事故越来越少
 ↓
团队越来越不依赖个人

所以我不太喜欢把 Postmortem 翻译成简单的“事故总结”。

它更像是一种组织的记忆机制

人会忘记。

新人会加入。

老员工会离职。

系统会重构。

代码会重写。

但是,如果一次事故最终变成了:

一条监控
一个测试
一个Runbook
一个自动化脚本
一个发布门禁
一条工程规范
一套培训材料

那么这场事故就没有白发生。

最好的事故复盘,不是让大家记住“谁搞砸了”。

而是让组织记住:

“我们曾经在这里摔倒过,所以以后不会再用同样的姿势摔第二次。”

这才是 Postmortem 最有价值的地方。

也是我理解的运维真正的成长:

从“我能把系统救回来”,到“我能让这个团队以后更不容易把系统搞挂”。

前者是运维能力。

后者,才是组织能力。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。