重试机制选择指南
2026/9/2 17:25:15 网站建设 项目流程

调用一个外部服务失败了,第一反应是再试一次。这个直觉没错,但「再试一次」从一句代码到生产可用的重试策略,中间隔着好几层坑——每一层都是被上一层的代价逼出来的。

起点:固定次数重试

最直觉的做法:失败就重试,重试 N 次,还不行就放弃。

foriinrange(3):try:returncall_api()except:continueraise

够简单,逻辑清晰。调用偶发失败的场景下完全够用。

但它有两个问题。第一,重试间隔是零。上一秒刚失败,下一秒立刻重试,被调方还没缓过来,你又打过去了。如果被调方是因为过载才失败的,零间隔重试等于火上浇油。

第二,重试会把延迟放大。一次调用 100ms,重试 3 次最坏 400ms。调用方多等一会儿没关系,但如果你在请求链路里,这个延迟会传到用户那一端。

指数退避:别打太勤

零间隔重试会加剧拥塞,于是想到:每次失败后等久一点再试。

指数退避就是干这个的:第一次等 1 秒,第二次等 2 秒,第三次等 4 秒——间隔指数增长。被调方如果是因为过载失败的,给它喘息的时间,别一上来就连着打。

但这引入了新问题:如果你有 10 个客户端同时调用同一个服务,服务挂了,10 个客户端都在等指数退避。第一次都在第 1 秒重试,第二次都在第 3 秒重试——大家步调一致,重试全挤在一起。服务刚缓过来一点,一波重试又打过去,又被压垮。

这叫惊群效应。指数退避解决了「重试太频繁」,但制造了「重试太整齐」。

加抖动:打散整齐的重试

解决惊群的方法是给退避加随机性——抖动。

本来第 2 秒重试,加个随机偏移,变成 1.7 秒或 2.3 秒。10 个客户端不再同时重试,而是分散在一个时间窗口里。被调方收到的重试从「一波打过来」变成「陆续打过来」。

抖动这步不起眼,但关键。不加抖动,指数退避只是把问题从「太频繁」推迟到「太整齐」;加了抖动,重试才真正分散开。

代价是延迟变得不可预测。同一个请求,你可能 2 秒重试成功,也可能 5 秒才重试。对于需要确定性延迟的场景,这个不可预测是新的麻烦。

重试加超时:一直不返回怎么办

到目前为止,重试策略解决的是「失败后怎么办」。但还有一个没解决:「一直不返回怎么办」。

被调方不一定每次都干脆地返回失败。更常见的情况是它卡住了——请求发出去,不返回成功也不返回失败,就这么挂着。你的重试逻辑根本触发不了,因为还没收到失败信号。

所以重试必须配合超时。单次调用设个超时,超时了就算失败,触发重试。否则一个卡住的请求能占满你的连接池,后面的请求全排队。

但超时设多少是个难题。设短了,正常慢请求被误杀;设长了,故障时干等。而且超时和重试次数会叠加:单次超时 3 秒,重试 3 次,最坏 9 秒。调用方愿意等这么久吗?

重试加熔断:别把故障放大

重试的本质是假设「失败是暂时的,再试一次可能成功」。但如果被调方是真的挂了,不是暂时抖动,你的每一次重试都是在给一个已经死掉的服务发请求。

更糟的是,你的重试会放大故障。正常情况下一个请求打一次,现在打三次。被调方本来就在勉强支撑,重试让它雪上加霜。如果被调方还有下游,重试的请求会一层层传下去,把一个局部故障放大成全局雪崩。

熔断就是干这个的:连续失败到一定次数,直接停止重试,也不再发新请求,快速失败。给被调方喘息的时间,也保护自己不被拖死。

熔断不是重试的替代,是重试的刹车。没有熔断的重试是「无脑试到死」,加了熔断的重试是「试几次不行就算了」。

怎么选

重试策略的演进,是被代价一层层逼出来的:固定重试太频繁 → 指数退避 → 退避太整齐 → 加抖动 → 还得防卡住 → 加超时 → 还得防放大故障 → 加熔断。

但实际工程中你不需要每次都从零搭。大多数场景的答案是:指数退避 + 抖动 + 超时 + 熔断,用现成的库。Java 的 Resilience4j、Go 的 go-resilience、Python 的 tenacity,都内置了这套组合。

真正需要你自己想清楚的是这几个参数:

  • 重试几次:3 次是个常见值,多了放大故障,少了不够兜底。
  • 退避多久起步:看被调方的恢复速度。秒级服务从 1 秒起步,分钟级任务从 30 秒起步。
  • 超时设多长:看调用方能接受的最长等待。链路越长,单次超时要越紧,给重试留余量。
  • 什么情况不重试:不是所有失败都该重试。参数校验失败、权限不足,重试一百次结果一样。只有「可能恢复的临时故障」才值得重试——超时、限流、网络抖动。非幂等的写操作更要慎重,重试可能导致重复写入。

最后一条最容易被忽略:重试的前提是幂等。如果被调方不保证幂等,重试可能把一次扣款变成两次。在重试之前,先确认你的操作能不能安全地重复执行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询