- Published on
著名事后复盘解剖 — 从 Cloudflare·Fastly·AWS·Knight Capital·GitLab 的失败中学习
- Authors

- Name
- Youngju Kim
- @fjvbn20031
前言 — “失败是最好的老师”
2025 年 4 月,你的服务在凌晨 3 点挂了。
- 原因: 不明
- 恢复: 2 小时
- 责任人: 昨晚提交代码的某个人
- 气氛: “谁干的?”
这就是 Blame culture — 一个无法从失败中学习的环境。
反过来,世界级的公司会 公开 Postmortem。Cloudflare、Google、AWS、GitLab。“我们是这样搞砸的,又是这样学到的”这种透明,会让 整个行业 一起学习。
如果说 Season 3 Ep 1 看的是这些公司的 成功 架构,那么 Ep 2 就是从 失败 中学习。
这篇文章是从公开的 postmortem 中提炼出的实战教训。让我们 用别人的成本 来避开同样的错误。
第 1 部 — 什么是 Postmortem
定义
Postmortem (事后分析): 在事件发生之后,把原因、影响、时间线、教训记录成文档。
Google SRE 书里的 5 要素
1. Incident summary
2. Impact (谁、多少)
3. Root cause (技术 + 流程)
4. Timeline (按分钟)
5. Action items (具体)
Blameless Postmortem 的核心
坏例: "Alice 推送了错误的 config"
好例: "Config validation 缺失。
Alice 的 change 能通过,说明是系统的缺口。"
哲学: 要修的是 系统,不是人。一旦开始责备,下一个人就会隐瞒。
第 2 部 — Cloudflare 2022-06-21 — BGP 让一半服务下线
发生了什么
2022 年 6 月 21 日 06:27 UTC
Cloudflare 的 19 个数据中心 (全球一半流量) 下线
客户服务受影响 1 小时 30 分钟
原因
BGP 路由变更中的失误:
Cloudflare 正在做网络标准化
在部分数据中心 rollout BGP configuration
Config 变更: 部分 prefix 停止广播 → 流量无处可去
为什么全都受影响?
中央 control plane 传播 config
多个 DC 同时受影响的结构
没有 Canary 的快速传播
教训
- Config change 也是一次发布: Canary 是必须的
- 中央控制的两面: 速度 vs 爆炸半径
- BGP 很危险: 一次失误就是互联网级别
- 透明的事后复盘: Cloudflare 在几小时内就公开了
Action items (Cloudflare 公布)
- 重新设计 Config 变更 workflow
- 更强的 staging 环境
- 强制 Progressive rollout
- 改进 Alert
第 3 部 — Cloudflare 2019-07-02 — 一个正则把 CPU 打到 100%
发生了什么
2019 年 7 月 2 日
Cloudflare WAF rule 更新 → 全球 CPU 100%
27 分钟内 HTTP 50x 上升
原因 — Catastrophic Backtracking
WAF rule 里的那个正则:
(?:(?:\"|'|\]|\}|\\|\d|(?:nan|infinity|true|false|null|undefined|symbol|math)|
`|\-|\+)+[)]*;?((?:\s|-|~|!|{}|\|\||\+)*.*(?:.*=.*)))
引发 "Catastrophic backtracking"
在部分输入下以指数时间运行
→ CPU 100% → 无法处理 HTTP
教训
- Regex 很危险: 一复杂就可能被 ReDoS 攻击
- WAF rule 是 global change: 一次修改影响全世界
- 需要做 CPU 测试: Latency + throughput 也要测
- Kill switch: 出问题时能立刻关掉
Cloudflare 的应对
- 评估 Re2 (Google) 这类 linear-time regex 引擎
- 对 WAF change 做 CPU profiling
- Rolling deployment (不再一次性推向全世界)
第 4 部 — Fastly 2021-06-08 — 一个客户让半个互联网停摆
发生了什么
2021 年 6 月 8 日 10:00 UTC
Fastly CDN 全球下线 (约 1 小时)
影响: Amazon、Reddit、CNN、NYT、PayPal、UK 政府网站
被报道为“互联网停了一半”
原因
一个客户改了某个 config
这个 config 触发了 Fastly 内部的软件 bug
→ 全球 edge 服务器 cache miss + 系统错误
→ 85% 的流量受影响
5 月就已经发布出去的 bug
5 月 12 日: 发布软件 (bug 被埋下)
6 月 8 日: 特定客户的 config 触发这个 bug
→ 潜伏的 bug 爆发
教训
- Multi-tenancy 的危险: 一个客户影响所有人
- Dormant bugs: 几周/几个月之后才爆
- Fast recovery: Fastly 在 1 小时内恢复 (令人印象深刻)
- 客户测试的极限: 无法模拟真实的 production mix
第 5 部 — AWS S3 2017-02-28 — 一个笔误让互联网停摆
发生了什么
2017 年 2 月 28 日 09:37 PST
AWS us-east-1 S3 下线 (约 4 小时)
影响: Slack、Quora、Trello、Medium、数千个站点
AWS 的“Service Health Dashboard”也因为要写 S3 而无法更新
原因
一位工程师在调试 billing 系统:
计划有意重启 S3 subsystem 的一部分服务器
但因为笔误重启了更多服务器
具体来说:
- 删掉了 Index subsystem + Placement subsystem 的核心服务器
- 这些 subsystem 就是 S3 core
- 需要完全重启 → 4 小时
教训
- 人的失误不可避免: 必须用工具来防
- Automation 的空缺: 破坏性命令没有确认 X
- Blast radius: 所有 subsystem 都在同一个 AZ
- Dashboard dependency: Status page 依赖同一套系统
AWS 的应对
- 为 Dangerous operations 增加 safeguard
- 改进 Command-line tool (类似 --confirm)
- 重新设计 Service 依赖
- 让 Status page 独立
第 6 部 — Knight Capital 2012-08-01 — 8 分钟亏掉 $440M
发生了什么
2012 年 8 月 1 日 上午 9:30 (纽约股市开盘)
Knight Capital (美国股票市场的主要 market maker)
8 分钟内损失 $440M
→ 公司几乎破产,3 个月后被收购
原因 — Dead Code Resurrection
背景:
- Knight 的交易系统里有多年未用的 "Power Peg" 功能
- 作为 dead code 留了下来
- 新功能发布时,8 台服务器里有 1 台部署失误
- 这台服务器把 "Power Peg" code 解读成 re-enable flag
- 开盘的同时开始疯狂生成订单
8 分钟内:
- 生成了数百万笔订单
- 不管价格 buy high, sell low
- 市场被扭曲
- 合计损失 $440M
教训
- 删掉 dead code: 不用的代码就是危险
- 发布自动化: 手动更新 8 台服务器是错误的温床
- 禁止复用 Feature flag: 同一个 flag 换个含义用就是灾难
- Circuit breaker: 异常订单没有被自动拦截 X
- Testing gap: 这个问题本该在 Pre-production 就被抓住
第 7 部 — GitLab 2017-01-31 — DB wipe
发生了什么
2017 年 1 月 31 日晚上
GitLab.com 数据库被 wipe
差点丢掉 300GB 数据 (可恢复: 约 6 小时 transaction 损失)
原因 — 人为失误 + 备份没起作用
情况: 在调试 DB replication 问题
主 DB 上 replication 乱了
工程师想清理 replica
失误 1: 对错误的 DB 执行了 rm -rf
→ 删掉了一部分 Production DB
恢复尝试:
备份 1 (daily pg_dump): 因为出错,文件是 0 bytes
备份 2 (LVM snapshot): 6 小时前的
备份 3 (S3 upload): 从没启用过
备份 4 (replica): 正是造成问题的那个
备份 5 (Azure 磁盘 snapshot): 可以恢复
→ 最终损失 6 小时的 transaction
创新的应对
Live-stream postmortem: GitLab 在 YouTube 上直播了整个恢复过程。 数万人观看。透明性的极致。
教训
- 备份要测试: 没有恢复过就不算备份
- 多种备份: 一个失败了还有别的
- 防止人为失误: Destructive command 要 double-check
- 透明: 对 GitLab 的信任反而上升了
第 8 部 — Facebook 2021-10-04 — 又是 BGP 干的
发生了什么
2021 年 10 月 4 日 15:40 UTC
Facebook、Instagram、WhatsApp 全球下线 6 小时
Facebook 员工也进不了大楼 (门禁 badge 系统也依赖它)
原因
BGP config 变更 → Facebook 的 DNS 服务器从 internet 上消失
内部工具也全部依赖 internet → 工程师无法恢复
物理门禁也受影响 → 无法进入数据中心
恢复:
- 物理进入数据中心
- 手动重置网络设备
- 恢复 BGP 广播
教训
- Out-of-band access: 主网络挂了也能进去的路径
- Dependency loop: 所有东西都依赖 Internet 就会 self-lockout
- 物理访问: 数字基础设施也需要物理空间
- BGP 的危险: 反复出现的模式
第 9 部 — Heroku 2021-04-13 — GitHub OAuth 令牌泄露
发生了什么
2021 年 4 月
Heroku 的 GitHub OAuth integration 令牌泄露
攻击者访问了数千个 Heroku 账号的 GitHub repos
Heroku 初期没有好好告知,失去了信任
教训
- Secret 管理: OAuth token 也是 secret
- Rotation: 定期更换
- 迅速 disclosure: 藏起来只会带来更大的危机
- Third-party risk: 集成就是漏洞的窗口
第 10 部 — Roblox 2021-10-28 — 停机 73 小时
发生了什么
从 2021 年 10 月 28 日起停机 73 小时
5 千万 DAU 的游戏平台
Black Friday 周末
原因
HashiCorp Consul (service discovery) 集群服务器负载
新功能对 Consul 产生了过量写入负载
Consul consensus 崩了 → 整体 downtime
特别之处
HashiCorp + Roblox 的联合事后复盘。厂商和客户一起分析。
教训
- Service discovery dependency: 核心必须极其稳定
- Chaos testing: 本该在压测里抓到
- Vendor collaboration: 责任共担模型
第 11 部 — Atlassian 2022-04-05 — 停机 14 天
发生了什么
2022 年 4 月
775 个 Atlassian 客户 (Jira、Confluence 等)
恢复花了 14 天
脚本错误导致数据被删
原因
legacy 功能 deprecation 的脚本
本该按“站点”粒度删除,却错传了“应用”粒度的参数
→ 客户整个站点的数据被删除
恢复: 从备份来,but 因为是客户数据,只能逐个手工处理
教训
- Destructive script 必须先 dry-run
- Backup per tenant: SaaS 多租户恢复的核心
- Restore 的速度: 有备份但恢复太慢,意义就减半
- 客户 communication: Atlassian 因初期应对不力而被批评
第 12 部 — 失败模式 10 种
在所有 postmortem 里都能看到的模式:
- 手工操作 + 失误 (Knight, AWS, GitLab)
- Config change without staging (Cloudflare)
- Dead code / 不再使用的功能 (Knight)
- Global rollout without canary (Cloudflare, Fastly)
- BGP (Facebook, Cloudflare)
- Backup 不起作用 (GitLab)
- Dependency loop (Facebook, AWS S3 dashboard)
- Multi-tenant blast radius (Fastly, Atlassian)
- Third-party integration risk (Heroku)
- Chaos testing gap (Roblox)
第 13 部 — Postmortem 模板
实战模板
# Incident: [Title]
Date: 2026-04-15
Severity: SEV1/SEV2/SEV3
Duration: 09:30-11:45 UTC (2h 15m)
Impact: X users affected, Y revenue lost
## Summary
[2-3 sentences]
## Impact
- Users: ...
- Revenue: ...
- Services: ...
- Customer communications: ...
## Timeline
- 09:30 UTC: Alert triggered
- 09:35 UTC: Engineer paged
- ...
## Root Cause
[Technical explanation]
Contributing factors:
- ...
## Detection
- How was it detected?
- Time to detect: X min
- Could it have been detected faster?
## Response
- Time to mitigate: X min
- What worked?
- What didn't?
## Recovery
[Steps taken to restore service]
## Lessons Learned
### What went well
- ...
### What went wrong
- ...
### Where we got lucky
- ...
## Action Items
| Item | Owner | Priority | Due |
|---|---|---|---|
| Add canary deployment | @alice | P0 | 2026-04-30 |
| ... | | | |
## Supporting Data
- Graphs, logs, screenshots
写作要点
- 事件后 48 小时以内 出初稿
- 多人评审 (所有相关的人)
- Action item 要 SMART (Specific, Measurable, ...)
- Follow-up: 2 周、4 周后检查 status
- 考虑公开: 哪怕只公开一部分也好
第 14 部 — 检查清单 12 项
- 把 Postmortem 模板引入团队
- 明确写出 Blameless 文化 + 做训练
- Action item tracking (Jira/Linear)
- 2 周/4 周的 follow-up 会议
- 真正 做一次备份恢复测试 (每季度 1 次)
- 开始 Chaos Engineering (从简单的做起)
- 强制 Canary / Progressive rollout
- Out-of-band access (楼宇/网络)
- Destructive command safeguard (--confirm)
- 定期清理 Dead code
- Incident response runbook
- Company-wide Game Day (每年 1 次)
第 15 部 — 反模式 10 种
- 先找是谁干的 → 责备文化
- 不公开 Postmortem → 同一个团队犯同一个错
- 不追踪 Action item → 纸老虎
- 开一小时会就结束 → 没有深度
- 把 Root cause 归为一个 → 复杂事件有多个原因
- “Just human error” → 回避系统设计问题
- 不是 SEV1 就不做 postmortem → 小事里也有收获
- 有备份就放心 → 从不做恢复测试
- 一直推迟 Chaos Engineering → 生产环境本身就是 Chaos
- Legal/PR 来编辑 Postmortem → 真相被稀释
收尾 — “失败很贵,但学习并不更贵”
Cloudflare、GitLab、AWS — 业界顶尖的公司用公开的 postmortem 在教 整个行业。 他们失去的: 100M+ 美元。 我们得到的: 免费的教训。
下一次你的服务挂掉的时候:
- 与其花时间责怪谁,不如 去修系统
- 与其花时间难为情,不如 写成文档
- 与其花时间隐瞒,不如 和团队分享
“能从失败中学习的组织才有竞争力”。这是 Google SRE 那本书 25 年前就说过的话。
下一篇是 Season 3 Ep 3 — 扩展拐点完全指南。 1 → 100 → 10K → 100K → 1M → 10M 用户各自的架构变化。什么时候做 DB 分片?什么时候上 Microservices?什么时候用 CDN?给出具体的临界点。
下期预告 — “扩展拐点完全指南: 100 → 10K → 1M 各用户量级的架构演进”
Season 3 Ep 3 会讲:
- 100 users: 单台服务器、SQLite
- 10K users: Rails + Postgres + Redis
- 100K users: read replica、缓存、CDN
- 1M users: read/write split、分片
- 10M users: 考虑 Microservices
- 什么时候该换语言?
- Real 公司的拐点
下一篇见。