给请求加了重试之后,订单接口一次读取超时被重发三次,服务端记下两条一模一样的单。日志里能对上时间点,这种反而好排。

Retry 默认不区分请求语义,POST 在读取超时后重放等于又提交一次,接口本身没有幂等键兜底就重复落库。这一点先确认清楚,后面就不用反复试。

from urllib3.util.retry import Retry
retry = Retry(total=2,
              allowed_methods=frozenset(['GET', 'HEAD']))
requests.adapters.HTTPAdapter(max_retries=retry)

围绕「requests 重试配置」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。

处理上按这个顺序:Retry 里只把 GET 和 HEAD 放进允许方法;写接口时带上请求号,服务端按它做幂等判断;只对 5xx 重试,遇到 4xx 直接放弃重发。

结果对不对很好判断,断网重连期间订单只生成一条,4xx 请求不再被重发。

作者 9823189