Skip to content

필사 모드: 著名事后复盘解剖 — 从 Cloudflare·Fastly·AWS·Knight Capital·GitLab 的失败中学习

中文
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

前言 — “失败是最好的老师”

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 让一半服务下线

发生了什么

202262106:27 UTC
Cloudflare19 个数据中心 (全球一半流量) 下线
客户服务受影响 1 小时 30 分钟

原因

BGP 路由变更中的失误:

Cloudflare 正在做网络标准化
在部分数据中心 rollout BGP configuration
Config 变更: 部分 prefix 停止广播 → 流量无处可去

为什么全都受影响?

中央 control plane 传播 config
多个 DC 同时受影响的结构
没有 Canary 的快速传播

教训

  1. Config change 也是一次发布: Canary 是必须的
  2. 中央控制的两面: 速度 vs 爆炸半径
  3. BGP 很危险: 一次失误就是互联网级别
  4. 透明的事后复盘: Cloudflare 在几小时内就公开了

Action items (Cloudflare 公布)

  • 重新设计 Config 变更 workflow
  • 更强的 staging 环境
  • 强制 Progressive rollout
  • 改进 Alert

第 3 部 — Cloudflare 2019-07-02 — 一个正则把 CPU 打到 100%

发生了什么

201972Cloudflare 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

教训

  1. Regex 很危险: 一复杂就可能被 ReDoS 攻击
  2. WAF rule 是 global change: 一次修改影响全世界
  3. 需要做 CPU 测试: Latency + throughput 也要测
  4. Kill switch: 出问题时能立刻关掉

Cloudflare 的应对

  • 评估 Re2 (Google) 这类 linear-time regex 引擎
  • 对 WAF change 做 CPU profiling
  • Rolling deployment (不再一次性推向全世界)

第 4 部 — Fastly 2021-06-08 — 一个客户让半个互联网停摆

发生了什么

20216810:00 UTC
Fastly CDN 全球下线 (1 小时)
影响: Amazon、Reddit、CNNNYT、PayPal、UK 政府网站
被报道为“互联网停了一半”

原因

一个客户改了某个 config
这个 config 触发了 Fastly 内部的软件 bug
→ 全球 edge 服务器 cache miss + 系统错误
85% 的流量受影响

5 月就已经发布出去的 bug

512 : 发布软件 (bug 被埋下)
68 : 特定客户的 config 触发这个 bug
  → 潜伏的 bug 爆发

教训

  1. Multi-tenancy 的危险: 一个客户影响所有人
  2. Dormant bugs: 几周/几个月之后才爆
  3. Fast recovery: Fastly 在 1 小时内恢复 (令人印象深刻)
  4. 客户测试的极限: 无法模拟真实的 production mix

第 5 部 — AWS S3 2017-02-28 — 一个笔误让互联网停摆

发生了什么

201722809: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 小时

教训

  1. 人的失误不可避免: 必须用工具来防
  2. Automation 的空缺: 破坏性命令没有确认 X
  3. Blast radius: 所有 subsystem 都在同一个 AZ
  4. Dashboard dependency: Status page 依赖同一套系统

AWS 的应对

  • 为 Dangerous operations 增加 safeguard
  • 改进 Command-line tool (类似 --confirm)
  • 重新设计 Service 依赖
  • 让 Status page 独立

第 6 部 — Knight Capital 2012-08-01 — 8 分钟亏掉 $440M

发生了什么

201281 日 上午 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

教训

  1. 删掉 dead code: 不用的代码就是危险
  2. 发布自动化: 手动更新 8 台服务器是错误的温床
  3. 禁止复用 Feature flag: 同一个 flag 换个含义用就是灾难
  4. Circuit breaker: 异常订单没有被自动拦截 X
  5. Testing gap: 这个问题本该在 Pre-production 就被抓住

第 7 部 — GitLab 2017-01-31 — DB wipe

发生了什么

2017131 日晚上
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 上直播了整个恢复过程。 数万人观看。透明性的极致。

教训

  1. 备份要测试: 没有恢复过就不算备份
  2. 多种备份: 一个失败了还有别的
  3. 防止人为失误: Destructive command 要 double-check
  4. 透明: 对 GitLab 的信任反而上升了

第 8 部 — Facebook 2021-10-04 — 又是 BGP 干的

发生了什么

202110415:40 UTC
Facebook、Instagram、WhatsApp 全球下线 6 小时
Facebook 员工也进不了大楼 (门禁 badge 系统也依赖它)

原因

BGP config 变更 → FacebookDNS 服务器从 internet 上消失
内部工具也全部依赖 internet → 工程师无法恢复
物理门禁也受影响 → 无法进入数据中心

恢复:
- 物理进入数据中心
- 手动重置网络设备
- 恢复 BGP 广播

教训

  1. Out-of-band access: 主网络挂了也能进去的路径
  2. Dependency loop: 所有东西都依赖 Internet 就会 self-lockout
  3. 物理访问: 数字基础设施也需要物理空间
  4. BGP 的危险: 反复出现的模式

第 9 部 — Heroku 2021-04-13 — GitHub OAuth 令牌泄露

发生了什么

20214HerokuGitHub OAuth integration 令牌泄露
攻击者访问了数千个 Heroku 账号的 GitHub repos
Heroku 初期没有好好告知,失去了信任

教训

  1. Secret 管理: OAuth token 也是 secret
  2. Rotation: 定期更换
  3. 迅速 disclosure: 藏起来只会带来更大的危机
  4. Third-party risk: 集成就是漏洞的窗口

第 10 部 — Roblox 2021-10-28 — 停机 73 小时

发生了什么

20211028 日起停机 73 小时
5 千万 DAU 的游戏平台
Black Friday 周末

原因

HashiCorp Consul (service discovery) 集群服务器负载
新功能对 Consul 产生了过量写入负载
Consul consensus 崩了 → 整体 downtime

特别之处

HashiCorp + Roblox 的联合事后复盘。厂商和客户一起分析。

教训

  1. Service discovery dependency: 核心必须极其稳定
  2. Chaos testing: 本该在压测里抓到
  3. Vendor collaboration: 责任共担模型

第 11 部 — Atlassian 2022-04-05 — 停机 14 天

发生了什么

20224775Atlassian 客户 (Jira、Confluence)
恢复花了 14脚本错误导致数据被删

原因

legacy 功能 deprecation 的脚本
本该按“站点”粒度删除,却错传了“应用”粒度的参数
→ 客户整个站点的数据被删除
恢复: 从备份来,but 因为是客户数据,只能逐个手工处理

教训

  1. Destructive script 必须先 dry-run
  2. Backup per tenant: SaaS 多租户恢复的核心
  3. Restore 的速度: 有备份但恢复太慢,意义就减半
  4. 客户 communication: Atlassian 因初期应对不力而被批评

第 12 部 — 失败模式 10 种

在所有 postmortem 里都能看到的模式:

  1. 手工操作 + 失误 (Knight, AWS, GitLab)
  2. Config change without staging (Cloudflare)
  3. Dead code / 不再使用的功能 (Knight)
  4. Global rollout without canary (Cloudflare, Fastly)
  5. BGP (Facebook, Cloudflare)
  6. Backup 不起作用 (GitLab)
  7. Dependency loop (Facebook, AWS S3 dashboard)
  8. Multi-tenant blast radius (Fastly, Atlassian)
  9. Third-party integration risk (Heroku)
  10. 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

写作要点

  1. 事件后 48 小时以内 出初稿
  2. 多人评审 (所有相关的人)
  3. Action item 要 SMART (Specific, Measurable, ...)
  4. Follow-up: 2 周、4 周后检查 status
  5. 考虑公开: 哪怕只公开一部分也好

第 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 种

  1. 先找是谁干的 → 责备文化
  2. 不公开 Postmortem → 同一个团队犯同一个错
  3. 不追踪 Action item → 纸老虎
  4. 开一小时会就结束 → 没有深度
  5. 把 Root cause 归为一个 → 复杂事件有多个原因
  6. “Just human error” → 回避系统设计问题
  7. 不是 SEV1 就不做 postmortem → 小事里也有收获
  8. 有备份就放心 → 从不做恢复测试
  9. 一直推迟 Chaos Engineering → 生产环境本身就是 Chaos
  10. 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 公司的拐点

下一篇见。

현재 단락 (1/258)

2025 年 4 月,你的服务在凌晨 3 点挂了。

작성 글자: 0원문 글자: 7,528작성 단락: 0/258