【背景】 SRE 干了 3 年,复盘会里见过最刺眼的一类事故不是"没发现",而是"发现得太快、动手得也太快":凌晨 2 点告警风暴,值班同学 30 秒内重启了 4 个副本,MTTR 很漂亮,第二天复盘才发现——重启把现场(堆内存、连接状态、慢查询日志、未落盘的脏页)全冲掉了,事后只能靠猜,根因拖了两周才定位到是上游一个慢 SQL 在批量打满连接池。 反过来也见过更糟的:DB 连接池打满,有人提议"直接重启 DB",被拦下来是因为重启会让 2000 条挂起的事务回滚、下游 6 个服务同时重试,差点把"单点故障"升级成"雪崩"。
【常见分歧 / 几种做法】
- 「先止血」派:MTTR 优先,重启 / 回滚最快、损失最小,"先恢复服务,根因慢慢查"。
- 「先查因」派:担心重启破坏现场、掩盖根因,甚至引发二次故障(连接未清理、锁未释放、消息重放、缓存雪崩),宁可硬扛 5 分钟先把堆 / 线程 / 慢查询 / 变更列表抓全。
- 「先回滚」派:最近 24 小时有变更 = 最大嫌疑,回滚是确定性止血,比重启更可控。
- 「看场景」派:无明确边界,全凭值班同学当时状态。
【我的倾向与理由】 默认"先止血",但止血前强制花 ≤60 秒做三件事:
- 抓现场快照(heap dump / jstack / 当前连接数 / 慢查询 Top10 / 最近 10 分钟变更列表),哪怕只是
ls -lt /var/log/+ss -s也比什么都没有强; - 判断重启的"二次故障面":这个服务重启会让谁重试、会不会触发锁竞争 / 消息重放 / 连接风暴;
- 评估有没有比重启更轻的止血手段:限流、降级、熔断、切流量,代价通常更小。 一句话:止血是默认动作,但"无脑重启"和"无脑回滚"都要先过一遍二次故障面清单。
【想听大家聊什么】
- 你团队有没有明确的"止血决策树"?还是全靠值班同学临场判断?
- 什么场景下你会选择"硬扛 5 分钟不重启"(比如必须等 heap dump 落盘)?什么场景下"无条件重启"(比如 OOM 已经发生)?
- 二次故障面清单你们怎么维护?是写在 runbook 里,还是每次复盘后补?补了之后真的有人看吗?
- 有没有"重启后根因彻底丢了"的教训?你们后来是怎么补现场的?
0赞
0收藏
0楼层