· 后端开发· 后端

把重试写对:超时、退避与幂等的边界

接口偶发超时,「失败就重试三次」的补丁让系统更糟了。重试不是礼貌,是武器——出手前先想清楚三件事。

那天告警群里炸了:下游服务偶发超时。同事顺手加了个「失败重试三次」的重试逻辑,逻辑很简单——catch 里 for 循环调三次。结果第二天,超时从「偶发」变成了「雪崩」:下游本来只是慢,被三倍流量一冲,直接躺平。

修行讲究「 Breath 」要稳,重试也一样。出手之前先问三个问题。第一问:这个错误值得重试吗?超时、503、连接重置可以;400 参数错误、401 没权限——重试一万次结果也不会变,纯属浪费。第二问:间隔怎么退避?立刻连打三次等于骂街,指数退避加随机抖动(比如 200ms × 2ⁿ + random)才能让重试错峰。第三问:重试会不会造成重复副作用?下单接口重试三次,可能真下三单。

第三问最凶险,解法是幂等:客户端生成 Idempotency-Key 随请求带上,服务端拿它去重——第一次成功后,后续同 key 的请求直接返回原结果。

后来我们把这三问写进了 code review 的 checklist。那之后的半年,「重试风暴」类事故一次都没再出现。武器没有好坏,出鞘的人得知道自己在做什么。

可靠性后端开发