一次线上故障的完整复盘
九月二十八号下午两点零六分,站点开始返回 502。十七分钟后恢复。这篇是完整的复盘记录,包括我们做错的地方。
时间线
| 时间 | 事件 |
|---|---|
| 14:06 | 监控告警,网关 502 比例超过阈值 |
| 14:09 | 值班同学介入,初步判断为后端服务不可用 |
| 14:12 | 发现数据库连接池打满 |
| 14:18 | 定位到某个慢查询,临时限流 |
| 14:23 | 服务恢复,错误率回落 |
根因
一个三年前写的定时任务,每天下午两点扫全表。三年前表里只有两万行,现在有两千万行。
1 | |
created_at 上没有索引。这个查询在小数据量时没问题,数据量涨了一千倍之后,单次执行从 200ms 变成 90 秒,直接占满连接池。
我们做错的三件事
- 监控只覆盖了结果,没覆盖趋势。 慢查询的执行时长是缓慢恶化的,如果有趋势告警,三个月前就该发现了。
- 没有对定时任务做资源隔离。 它和在线请求共用连接池,一个离线任务拖垮了在线服务。
- 恢复依赖人工判断。 从告警到限流花了十二分钟,其中七分钟花在”确认是不是这个问题”上。
改进行动
- 给所有定时任务单独的连接池,上限为在线池的 20%
- 补齐慢查询趋势告警,超过历史均值三倍即触发
- 为这类”已知可疑查询”准备一键限流脚本,把恢复时间压到两分钟内
故障本身不复杂,复杂的是它安静地恶化了三年却没人发现。这才是真正要修的东西。
一次线上故障的完整复盘
http://example.com/posts/incident-review/
如果这篇文章对你有帮助,可以请我喝杯咖啡
金额随意,备注一下昵称我会看到
微信
支付宝