凌晨两点半,我在书桌前盯着日志文件发呆(对,就是一台笔记本一盏台灯那种画面,跟二十年前的程序员没什么区别)。
事情是这样的:上个月交付数据同步模块,我给失败重试加了个上限——超过八次就放弃走兜底。这个逻辑是让 AI 写的,当时我逐行审过,没看出问题。上线一周都没事,今晚上线了一个小版本,就晚上十点多开始,日志里越刷越多重试记录,每条的报错信息都指向对方接口超时。我当时第一反应是对方服务挂了,还去问值班同事(午夜十二点,人家回我:我们这边一切正常。言外之意让我自己查)。
我盯着日志看了二十分钟,发现一个不对的地方:有个任务重试了二十多次还活着。按逻辑,应该八次就到上限了。我赶紧翻代码——AI 生成的那个判断:
if retry_count > retry_max: break
retry_count 是从 0 开始计数的,重试次数到达第八次时它等于 7,第七次等于 6……不对,问题不在这。问题在,重试前把 retry_count 自增了,但判断用的是旧值,也就是说其实可以跑到第九次、第十次,才被拦下来。八次的上限,实际能跑十几二十次。而那边接口偶发超时,超时了又继续重试,重试了又超时,死循环。
整个晚上我一直在查网络,查对方,查连接池,完全没往自己的重试逻辑想。因为日志里的报错是"Timeout"四个字,太有迷惑性了,我顺着它查了俩小时。最后还是按做测试的习惯,把日志里的重试数据拉出来数了一遍,才看出来"第 N 次重试"和 N 对不上。
修的话很简单,一行判断的事。但是我很气——气的是 AI 生成的代码我审过一遍,没审出来。这要是放以前提测,我肯定用例先锁上再放行。这次没写用例,就放上去了,被打脸了。不知道我描述清楚没有,就是那种"你知道会出事,但出的事跟你预想的不一样"的无力感。
改完重新部署,确认重试数到八就停了,日志干净了,我才发现已经很饿了。冰箱里剩半包鸭脖,就着凉白开吃掉,回到书桌又看了两轮日志,确认没有别的任务还在跑(那种在跑的可以手动终止,先这样吧)。跟值班同事说了声解决了,没敢说根因是自己这边的判断写错了,只说"重试条件有个边界没设置对",人家也没追问。
按我做测试的习惯,明天补一个重试上限的用例,锁死了再睡个安稳觉。想到再补吧,现在太困了。