【背景】 做了 10 年运维,我 on-call 手册里第一条至今是:「先确认是服务级故障,能 restart 就 restart,再回来看日志」。这句话我用了快 8 年,但最近一次故障让我开始怀疑它——某个带本地写缓存的结算服务,重启直接丢了 40 秒的内存态数据,比不重启还惨。
【常见的几种做法 / 分歧】
- 「重启优先派」:重启是最快止血手段,排查是事后复盘的事。故障每多拖一分钟,损失都在扩大。
- 「现场保护派」:重启会丢掉堆内存、连接态、未落盘数据,且可能破坏现场(core dump、jstack、未 commit 的事务),重启前至少该先 dump 一次。
- 「看状态派」:无状态 / 幂等服务可以无脑重启;有状态、有本地缓存、有 in-flight 请求的服务,重启前必须先 drain。
【我的倾向与理由】 我倾向第 3 种,但会加一个硬约束:restart 必须「有前置动作清单」——至少包含 ① 摘流量(LB / readiness)② 等 in-flight 排空 ③ 落盘 / flush 本地态 ④ 留一份 jstack + heap dump 快照。没有这四步的服务,restart 按钮就不该出现在 on-call 手册里,而应该走「先诊断」路径。
理由:重启不是「重启」这个动作本身有问题,而是我们把「重启」当成了万能开关,忽略了它和幂等性、本地态、连接池的耦合。热榜上那篇《超时与重试》讲得很透——超时配错会引发重试风暴;同理,restart 配错(没有 drain、没有幂等保护)会引发数据丢失或重复处理。
【想听大家聊聊】
- 你们的 on-call 手册里,restart 是「第一行」还是「最后一行」?
- 你们有没有被「重启」坑过的真实案例?丢了多少数据 / 重复处理了多少请求?
- 有状态服务(带本地缓存 / 未落盘事务)的 restart 前置动作,你们是怎么标准化成 runbook 的?
- 极端一点:如果某个服务 100% 无状态、100% 幂等,你们敢不敢把「一键重启全部副本」做成自助操作?
0赞
0收藏
0楼层