接口超时重试导致重复下单,该按什么顺序排查

一次促销活动结束后,客服陆续收到同一位用户的两笔订单,商品相同、金额相同、收货地址相同,下单时间只差几秒。技术同事第一反应是用户手快点了两次,但翻看日志发现,用户只提交了一次,问题出在接口超时后的自动重试上。这类重复下单并不罕见,超时本身不可怕,可怕的是重试发生时系统没有能力识别“这其实是同一件事”。排查这类问题,顺序比速度更重要。

先分清超时发生在哪一层

很多人一上来就改重试次数,结果掩盖了真正的问题。第一步应该定位超时点:是客户端等待超时,是网关转发超时,是服务端业务处理超时,还是数据库写入超时。四种情况的含义完全不同。客户端超时往往意味着用户已经离开页面,但请求可能仍在服务端执行;网关超时可能是后端响应慢,也可能是连接池被打满;服务端处理超时说明业务逻辑耗时超出预期;数据库写入超时则要警惕事务是否已经提交成功。定位不到层,后面的核对都是盲猜。

再核对重试策略的细节

确认超时层之后,看重试是怎么发生的。重点核对三件事:重试次数上限、重试间隔,以及每次重试是否携带同一个唯一请求标识。前两项决定重试的密度,第三项决定服务端有没有机会识别重复。如果每次重试都生成新的请求标识,服务端会把它当成全新请求处理,重复下单几乎无法避免。反过来,只要重试携带稳定标识,服务端就有了去重的基础。

接着看业务侧的幂等设计

唯一请求标识只是入口,真正拦住重复订单的是业务层的幂等规则。核对订单号生成方式,是否与请求标识绑定;核对去重键,是放在缓存、数据库唯一索引还是状态机判断里;核对订单状态流转,是否允许同一笔业务从“待支付”被重复创建。常见漏洞是去重逻辑写在应用层,但并发时两个请求同时通过了检查,最终都落了库。这时唯一索引往往比应用层判断更可靠。

按时间线把证据串起来

排查进入验证阶段,建议按固定顺序比对三类记录:日志时间线,把首次请求、超时、重试请求、订单创建时间排在同一张表上;请求标识追踪,确认每次重试携带的标识是否一致;状态变更记录,看订单表里是否出现两条独立记录,以及它们的状态流转是否同步。三者对照,基本能还原重复下单的完整路径。

预防比补救更省成本

可落地的做法包括:重试必须携带稳定请求标识;关键写入操作加数据库唯一约束作为兜底;订单创建与状态变更放在同一事务边界内评估;对超时接口设置合理的重试上限和退避间隔;上线前用并发场景做一次重复提交测试。这类链路问题往往横跨客户端、网关和业务服务,单看某一层很难发现。it数运在软件维护中处理类似问题时,通常会先协助梳理请求从发出到落库的完整路径,把超时点、重试点和幂等点标在同一张链路图上,再逐段核对,避免只改一处却留下新的重复入口。

© 版权声明
THE END
点赞11 分享