一次部署事故复盘:两个检出互相覆盖,线上回到了昨天

#部署#CI#事故复盘发布于 2026-09-11

事情起于一个很朴素的现象:栏目重构明明已经合并,线上打开还是旧的样子。第一反应是缓存,清完缓存刷新,页面确实变了——但变回去的是更早的版本,有几个页面凭空消失。

顺着时间线排查才看清楚:同一台服务器上先后有三个来源的检出在交错部署。一个来自 CI 流水线,一个来自手动同步,还有一个是几天前没关掉的临时任务。谁后写谁覆盖,构建产物目录被不同进度的代码轮流刷了一遍。

这次事故里最值得记的一点是「本地预览正常」。本地只有一份代码,自然是对的;而线上是不是对的,取决于最后一次写入是谁写的。同一个现象在本地永远复现不出来,所以第一轮排查方向就偏了。

第二个坑是 CI 没拦住。流水线只校验了构建是否成功,没有校验「构建产物是否来自当前这次提交」。构建成功和部署正确是两件事,中间那一环当时是空的。

改法有三条,都不复杂:一是部署入口收敛成一个,手动同步的口子关掉;二是部署加串行锁,连续触发只保留最新的一次,避免排队任务用旧产物覆盖新产物;三是构建后加一步产物校验,比对产物里的页面清单和源码实际数量,对不上就让流水线失败。

事后回看,这类「静默丢失」比直接报错危险得多。报错会立刻停下来,而覆盖是无声的,等你发现时已经过去了几天,中间所有排查都会走弯路。

← 返回经验分享