上线前的最后一次检查,应该交给清单而不是记忆
凌晨两点被叫起来回滚的工程师,事后复盘时通常会说同一句话:这条改动的风险其实想过,只是当时觉得不会出事。
上线事故的成因极少是「不知道」,绝大多数是「知道但没检查」。记忆在压力和疲惫下并不可靠,所以工程上更稳妥的做法是把关键动作从脑子里搬到一张可勾选的清单上。
清单不是流程文档,是防呆装置
好的清单有三个特征:每一项都能被验证,只有通过和不通过两种状态;每一项都有人负责,不写「团队确认」;每一项都标出通过的具体条件,而不是重复标题。
举个例子,「性能达标」是不可验证的,「接口响应时间的九十五分位在双倍峰值下低于四百毫秒」才是。区别在于前者需要主观判断,后者只需要看一眼监控。
一份最小可用的交付清单
- 构建与测试:流水线通过,冒烟测试在目标环境跑过一遍
- 配置与密钥:没有硬编码密钥,线上配置与预期一致,逐项比对
- 数据变更:迁移脚本在快照上试跑过,行数对得上,出错可以复原
- 回滚:不仅写了步骤,而且在预发环境真的演练过,能在几分钟内完成
- 可观测性:新增逻辑有日志和指标,出错时能定位到具体环节
- 开关:涉及新功能的,准备一个能立即关闭的开关,并确认默认状态
第四条是最常被跳过的一条。文档里写了「可回滚」和真的演练过一次,是两种完全不同的可靠性。前者是承诺,后者是证据。
一次没有演练导致的教训
某团队上线前确认了回滚方案:把服务版本切回上一个镜像。上线后出现数据写入异常,真正执行回滚时才发现,新版本的数据库结构变更不兼容旧版本代码,切回去之后服务直接起不来。
问题不在方案写得不清楚,而在没有人问一句「上一次真的切回去是什么时候」。凡是没验证过的兜底方案,都只是一句安慰。
灰度与开关的顺序问题
渐进式发布的常规做法是先放百分之一,观察错误率和关键指标,再逐步放到百分之五、百分之二十,最后全量。这条路径的前提是每一步的观察窗口足够长,能看到真实波动。
常见错误是灰度只放了十分钟就全量,等于没放。另一个错误是发布和开关同时开启,出了问题分不清是版本还是开关配置引起的。
让清单活下来的两个细节
第一,每次事故之后往清单里加一条,而不是加一段总结。清单应该是一份不断被事故喂养的资产。第二,把清单接进流水线:能自动检查的(测试状态、构建体积、密钥扫描)就不要靠人肉勾选,人的注意力应该留给判断类的事情。
清单的作用不是让人变得谨慎,而是让谨慎变得不依赖状态。人总会累、会赶、会侥幸,清单不会。
下一次发版前
把这份清单复制下来,把里面每一条换成你们自己的具体指标,然后安排一次回滚演练。演练一次之后,整张清单的可信度会完全不一样。