AI 编程最危险的时刻,是系统恢复以后

7 月底,我用 Claude Code 协助做的一套内部经营仪表盘,突然打不开了。

这套东西会定时把业务数据拉回来,整理成图表,再通过加密通道让同事用网页查看。我不会独立编程,这个也得先说明。代码和测试主要由 Claude Code 帮我完成,需求怎么定、哪些数字才算对、改完能不能上线,由我负责。

网络恢复后,多项任务和请求同时回到系统

网络恢复后,积压的任务和新的请求可能同时回到系统。

系统在 7 月中旬开始投入使用,此前一直跑得挺稳。偶尔出点小问题,也很快就能恢复。所以这次网络中断以后,我也觉得等网络恢复就行了。

页面先是打不开。网络恢复以后,我原以为事情已经结束了。可多个浏览器标签页同时刷新,系统还没来得及把数据重新准备好,就收到了一批重复计算的请求。页面又每隔 15 秒自动请求一次,访问越来越慢,到后来又打不开了。

网络恢复了,系统却没有跟着恢复。

这次我才发现,代码直接报错反而好判断。更麻烦的是 Claude Code 回复「已经修复」,页面也暂时能打开,我就会以为事情做完了。

我让它加重试,它就加。让它临时保存结果,它也照做。但我没有继续问,这些东西刚好一起启动时会怎样。

完整的排障过程挺长,这里就不全写了。我只记一下这次补上的五个问题。

1. 系统坏了以后,恢复过程也要测

以前我理解的系统状态只有两种,正常,或者坏了。

页面能不能正常返回结果,网络断了会不会提醒,程序停了能不能重新启动。这些测试补上以后,我就会觉得安全了不少。

后来才发现,正常和坏掉中间,还有一段恢复过程。

系统经历正常、故障与恢复三个状态

网络一恢复,积压任务、页面刷新和数据重新计算可能一起开始。

网络一恢复,没跑完的任务开始补,旧页面一起刷新,定时任务还照常在跑。之前保存的临时结果又刚好过期,几拨活一下撞到了一起。

后来我把已经准备好的临时结果清掉,同时打开多个页面,再断开和恢复网络,专门看恢复过程会不会把系统拖慢。以后做类似服务,这一步我会保留。

2. 自动重试有时会让系统更忙

以前页面请求失败,会每 15 秒重试整套数据。

我当时看到自动恢复,心里其实挺踏实。失败了自己再试,总比让用户一直点刷新方便。

后来才发现,每次重试都会再发一批请求。系统已经忙不过来时,页面每隔 15 秒再请求一次,只会让它一直忙下去。

自动重试形成循环,不断把请求送回繁忙的系统

系统忙不过来时,固定间隔重试会让新的请求一圈圈回来。

后来我们把两次重试的间隔拉长,也让不同页面稍微错开。同一个标签页只允许一轮刷新,切到后台就暂停。系统忙不过来时,也不再把所有耗时任务都接下来。

后来每加一段自动重试,我都会再检查一次,系统已经忙不过来时,它会不会还在不停发请求。会的话,就限制次数,超过以后直接停。

3. 任务拆开了,底下可能还共用同一套东西

这套系统早就把数据任务拆开了。历史数据按天处理,大区间拆成小区间,单次任务确实轻了很多。

我以前会自然地觉得,既然都拆开了,一个任务坏掉应该不会影响其他任务。

但所有小任务仍然共用同一条网络、同一套登录、同一个数据存放位置和同一条访问通道。所以一个地方出问题,其他任务还是会受影响。

多个拆开的小任务仍然连接着同一个故障点

任务拆小了,但它们还共用同一条网络和访问通道。

后来我们改了几处。一个数据来源失败后,后面的来源继续处理。主要访问通道换成 Tailscale,还保留了一条不同路线的备用通道。程序也不能只说任务完成,得确认新数据真的存下来了,页面才显示成功。

现在看到它说任务已经拆开,我还会继续看网络、登录和数据存放是不是仍然共用。如果这些还绑在一起,一个任务出问题,其他任务照样可能受影响。

4. 平时快,不代表刚恢复时也快

平时数据已经提前准备好时,页面几毫秒就能返回。我以前看到这个结果,会觉得速度问题已经解决了。

我之前没测的是,没有现成结果时,多个人同时打开页面会怎样。当时十几个标签页一起进入最耗时的趋势页面,同一份数据被重复查询和整理了十几遍。

后来我们改了一条规则。同一份结果只让一个请求真正计算,其他请求在旁边等同一个答案。16 个页面同时请求同一份结果,最终只计算一次。

多个页面请求排队汇入一次计算,再共享同一个结果

多个页面可以一起等待同一次计算,不必各自从头做一遍。

后来再测速度,我会先清掉已经准备好的结果,再同时开很多页面,顺便重启一次程序。只测数据已经准备好的情况,结果会比实际使用好看很多。

5. 测试只能检查写进去的问题

事故以前,这套仪表盘并不是没有测试。

关键数字有一份正确答案作为对照,修改计算规则后会逐项核对。网页代码和配置文件也会自动检查。那些测试当时全部是绿的。

原来的测试主要检查数字对不对、代码能不能运行。我们当时根本没写,多人同时打开页面会怎样,浏览器已经放弃等待以后,系统会不会还在后台继续计算。

这些场景没有被主动补上,我也没有问。回头看,测试全绿没有错,只是我们测的范围太窄了。

后来我们把这些情况都补进了发布前检查,包括多人同时打开页面、单个数据来源失败、简单页面能不能继续使用,还有备用通道切换。页面也把数据停止更新、无法连接、等待超时和系统繁忙分开,不再全部显示成一句「数据刷新失败」。

处理完以后,趋势页面恢复到约 1.5 秒。16 个页面同时请求同一份结果只计算一次,简单的状态页面在耗时计算期间仍然可以打开。我们也主动断开主通道做过切换演练,备用通道可以继续提供服务。

测试照亮已知问题,风险藏在没有被提问的地方

恢复过程和多人访问没有写进测试,自然也不会被测试发现。

不过,系统现在仍然有很明确的限制。

系统还是只跑在一台机器上,当前这套轻量服务也扛不住不断增长的访问量。如果以后使用人数继续增加,单机部署还得继续改。

这次故障没有让我觉得 Claude Code 不靠谱。没有它,我大概也做不出这套系统。只是哪些场景必须测,不能等它主动提醒我。

以后看到 Claude Code 回复「已经修复」,我不会马上把任务关掉。我会再断一次网络,再同时打开几个页面,然后看一眼数据到底有没有更新。

张玉魁的头像

张玉魁 / Ktao

临床医学在读。白天学医,其余时间把真实企业的客服、内容、数据和报表变成每天在跑的自动化系统。

评论

0 / 200
评论

加载中…