如何构建一份真正能防止生产事故的部署清单

如何构建一份真正能防止生产事故的部署清单

💡 原文英文,约3200词,阅读约需12分钟。
📝

内容提要

部署清单应区分应用风险与基础设施风险。应用风险需基于自身事故定制,关注回滚、配置、数据库迁移等;基础设施风险应自动化,而非人工检查。清单应精简,置于代码仓库,并明确回滚触发条件。自动化程度越高,部署越安全频繁。

🔎

延伸解读

区分应用风险与基础设施风险

文章建议将部署清单中的项目分为两类:应用风险和基础设施风险。应用风险与你的代码、数据和发布方式相关,需要人工判断;而基础设施风险(如证书、负载均衡、镜像来源)是重复性的平台责任,应尽可能自动化。判断标准是:如果某项检查在任何公司都相同,那它就不需要你的团队手动检查。

从事故中构建清单

不要试图列出所有可能的检查项,而是回顾过去十次事故,找出哪些检查本可以防止它们。通常三四个关键原因就能解释大部分故障。清单应精简,并放在代码仓库中,随每次部署更新。每个项目要么自动化,要么解释为何不能自动化,因为依赖人工记忆的检查最终会失败。

数据库迁移与回滚的陷阱

数据库迁移是回滚失败的主要原因。文章强调采用“扩展-收缩”模式:先添加新列,再逐步迁移代码,最后删除旧列,避免在同一部署中同时修改代码和数据库。此外,回滚触发条件应在部署前明确,例如错误率超过1%持续两分钟,而不是在压力下临时决定。

部署与发布分离

部署(代码上线)与发布(用户可见)应通过功能开关分离。先部署但关闭新功能,确认健康后再逐步开放给内部、1%用户,最后全量。这样如果出现问题,只需关闭开关,无需重新部署。同时,功能开关应设置清理日期,避免死代码积累。

Q&A

部署清单应该包含哪些内容?

部署清单应主要包含应用风险相关的检查项,这些检查项基于团队自身的事故历史定制,例如数据库迁移、配置、回滚等。基础设施风险(如证书、负载均衡等)应尽可能自动化,而不是人工检查。清单应精简,并放在代码仓库中。

如何区分应用风险和基础设施风险?

应用风险是与具体代码、数据、配置相关的风险,例如数据库迁移是否可逆、旧消费者能否读取新任务负载等,这些只有团队自己知道。基础设施风险是通用的平台责任,如证书是否有效、镜像是否来自正确提交、自动扩缩容规则是否正确等,任何公司都面临。如果一项检查可以原封不动地复制到其他公司的清单中,那它更可能是基础设施风险。

为什么部署清单要基于自身事故来构建?

因为自身的事故最能反映团队特有的应用风险。通过回顾最近的事故,找出哪些检查本可以防止它们,通常会发现少数几个原因(如配置错误、不安全的数据库迁移、依赖未就绪、回滚失败)导致了大部分故障。基于这些定制清单,比包含大量通用但无人执行的检查项更有效。

部署时如何处理数据库迁移?

数据库迁移必须采用扩展和收缩(expand and contract)模式,不能将模式变更和依赖它的代码同时部署。具体步骤:先添加新列(可空),部署代码同时写新旧列,然后回填数据,再部署代码读取新列并保留回退兼容,最后在几周后删除旧列。这样每一步都保证新旧代码可以同时运行,支持快速回滚。

部署和发布有什么区别?为什么要分开?

部署是指代码已经运行在服务器上,发布是指用户能够访问到新功能。分开它们可以降低风险:通过功能开关(feature flag),先部署代码但保持功能关闭,然后逐步开放给内部用户、小比例用户,最后全量。如果出现问题,只需关闭开关,无需重新部署。

如何确定回滚触发条件?

在部署前就明确回滚触发条件,例如错误率超过1%持续2分钟、95分位延迟超过正常值两倍、队列深度持续增长等。当任一条件满足时,立即回滚,无需讨论。同时要确保监控能够及时检测到这些信号,否则需要改进监控。

为什么基础设施风险应该自动化而不是人工检查?

因为基础设施风险是重复性的平台责任,人工检查容易出错且效率低。自动化可以确保持续一致地执行,例如证书自动续期、镜像来源验证、配置漂移检查等。自动化程度越高,部署越安全频繁,团队可以专注于应用风险。

部署清单应该放在哪里?

部署清单应该放在代码仓库中,最好作为拉取请求模板的一部分,这样每次部署时都会提醒开发者。清单应保持精简,例如包含六个检查项,而不是一个冗长的维基页面。

🏷️

标签

➡️

继续阅读