1805 字
9 分钟
一次上线事故教会我的三件事:清单、验证、同步

时间说明:事故发生在 2021 年 5 月 20 日,问题于次日发现。

2021 年 5 月 20 日 19:00,我发布了一个看似简单的需求:在申请流程中增加一项必填校验。

开发前,我因为疏忽忘记了这项任务,只能将发版推迟一天。开发时,我发现正常申请入口和另一个业务入口共用了部分逻辑,但两个入口能提供的信息并不相同。我没有继续确认另一个入口的实际调用情况,按自己的理解完成了修改。

发版后,我没有等待完整回归,也没有查看线上日志,便离开了。直到第二天,同事发现了问题。

这次事故涉及的技术并不复杂。问题出在三个环节:任务推进、影响面判断和发版后观察。我都把「应该没问题」当成了事实。

一、任务不能只记在脑子里#

这次问题最早出现在发版前一天。我忘记了自己的任务,直到临近发版才开始补救。任务推迟后,我也没有确认所有相关人员是否都知道这个变化。

当时我以为,只要自己记住任务就够了。但一个任务除了「要写什么」,还包括依赖谁、何时提测、何时发版,以及计划变化后需要通知谁。只记住开发内容,并不等于管理好了任务。

更可靠的做法是把任务写进清单,每天至少检查一次。清单不必复杂,但要回答几个问题:

  • 当前要交付的结果是什么?
  • 还依赖谁提供信息、Review 或测试?
  • 下一个明确时间点是什么?
  • 如果计划变化,需要通知哪些人?

清单用来减少遗漏,不必追求形式。计划发生变化时,也不能把「某个人知道」当成「所有人已经达成共识」。涉及提测和发版的变化,需要明确同步,并确认关键人员已经收到。

二、「我以为」不能代替验证#

这次修改最大的风险,是我在影响面不清楚时,仍然确信自己的判断。

现在回看,当时至少有三个问题没有回答:

  1. 这项校验是否真的需要由服务端强制执行?
  2. 另一个入口是否也能提供校验所需的信息?
  3. 修改公共逻辑后,两个入口分别需要回归哪些场景?

我没有通过代码、日志或实际请求确认这些问题,也没有把两个入口的差异明确告诉测试人员。个人猜测就这样代替了可以验证的信息。

会影响业务行为的判断,都要尽量变成可以验证的事实。

关心入口差异,就检查两个入口的请求参数和调用关系;关心历史数据,就抽样确认旧数据是否满足新条件;无法自己确认,就把问题、可能影响和待验证项明确交给产品或测试。

提问能把风险尽早暴露给相关人员。独自消化一个不确定点,往往只是让风险晚一点暴露。

AI 让猜测看起来更像答案#

这次事故发生时,AI 编程助手还没有进入我的日常开发。现在,AI 已经能参与需求拆解、代码生成、测试编写和问题排查。它能加快实现,也会让「我以为」变得更隐蔽。

过去,我不确定一个概念时,可能直接按自己的理解写代码。现在,我可能会先问 AI。如果提示里缺少关键上下文,AI 就可能虚构一个看似合理的概念、接口或调用关系。回答越完整、语气越肯定,我越容易把「AI 这么说」误认为「事实已经得到确认」。

AI 还能继续基于错误前提生成实现和测试。代码能运行,测试也可能通过,但它们验证的可能只是同一个错误假设。整个开发流程可能因此建立在未经确认的概念上。

与 AI 沟通时,不能只要求它给出答案,还要改变提问和验收方式:

  • 要求 AI 区分已知事实、推测和修改建议,并提供对应的代码、文档或日志依据。
  • 对 AI 提出的新名词、字段、接口和调用关系,回到源码与真实环境中验证;找不到依据,就不进入实现。
  • 除了让 AI 生成代码,也让它列出反例、影响入口和验证清单,用独立证据检查结果,避免同一个错误前提被反复用于自证。

AI 适合帮助我们提出假设,事实仍要自己验证。自己的经验、同事的建议和 AI 的输出,在进入生产前都应接受同样的检查。

三、代码发布不等于任务完成#

发版后没有观察日志,是这次事故中最直接的责任缺位。

当时我把「代码已经发布」当成了任务终点。但从用户角度看,发布只是变更开始影响真实流量的时刻。测试环境无法覆盖所有数据、入口和调用组合,发版后的观察正是最后一道及时发现问题的机会。

一次完整的交付,至少应包含发版后的几个动作:

  • 查看错误日志,确认是否出现新增异常。
  • 观察与本次修改直接相关的业务指标。
  • 验证最重要的正常流程和受影响入口。
  • 出现异常时,及时同步影响,并按预案回滚或修复。

观察什么,应当在发版前就确定。否则发版后面对大量日志和指标,很容易变成随便看一眼,甚至完全不看。

回滚方案也不应在出问题后才临时讨论。代码如何回退、配置如何恢复、数据变更是否可逆,都属于交付的一部分。

一份更实用的检查清单#

日常开发中,可以用三个问题检查自己的交付过程。

开发前:确认任务边界。

写清需求目标、影响入口、依赖人员和交付时间。遇到不明确的地方,尽早提出,别急着按自己的理解实现。

发版前:验证关键判断。

检查不同入口、异常参数、历史数据和兼容场景。把测试需要关注的差异明确说出来,不要指望别人自动知道自己的修改思路。

发版后:观察真实表现。

查看日志和业务指标,验证核心流程,明确观察责任与回滚方式。确认没有异常后,再把任务标记为完成。

这三件事都不复杂,坚持做却能减少很多交付问题。

把功能写出来只是第一步。任务清楚、判断有据、风险可见,才是一次可靠的交付。

一次上线事故教会我的三件事:清单、验证、同步
http://tech-blog.27k.online/posts/release-incident-lessons/
作者
K7
发布于
2026-11-01
许可协议
CC BY-NC-SA 4.0