跳到正文

重试与退避

Retry with Backoff

高级通用

重试与退避(Retry with Backoff)是在请求暂时失败后,隔一段时间再试,并逐步拉长等待时间的做法。它能让网站或 App 在外部服务短暂故障时恢复请求,也能避免立刻连续重试,加重对方的负担。

你可能会说:「调用外部接口偶尔失败时,我想让它过会儿再试,但别一直猛发请求。」

读之前建议先了解(这是一个高级概念)

动手看看

销售报表同步
首次请求失败报表服务暂时没有响应,客户端准备重试。
重试 1等待 0.1 秒
重试 2再等 0.1 秒
重试 3再等 0.1 秒
重试 1等待 0.6 秒
重试 2再等 0.6 秒
重试 3再等 0.6 秒
重试 1等待 0.3 秒
重试 2再等 0.7 秒
重试 3再等 1.4 秒
第三次重试恢复连接
重试节奏

切换重试节奏,观察三个卡片依次弹起的时间;改参数会自动重播,也可以点「重播」。弹起代表发起一次请求,绿色表示这次恢复成功。

逐步退避把等待从 0.3 秒拉长到 0.7 秒、1.4 秒:短暂故障能较快恢复,持续故障则会收到越来越少的请求。

要点

  1. 1

    先判断失败是不是暂时的

    比如服务短暂不可用、网络连接中断,稍后再试可能成功;参数写错或权限不足,等多久通常也没用。你可以让 AI 先列出可重试的错误,而不是把所有失败都交给重试处理。

  2. 2

    等待时间逐次拉长并错开

    如果每次失败都立刻重发,故障中的服务会收到更多请求。退避会让两次尝试之间的等待逐渐变长;加入少量随机偏移,还能减少许多用户同时失败、又同时重试造成的请求高峰。

  3. 3

    给重试设终点并检查副作用

    重试次数和总耗时都要有上限,否则用户可能一直等不到结果。读取数据通常容易重试;创建订单、扣款这类写入请求,可能已执行成功却没收到响应,重试前还得确认如何避免重复执行。

容易混淆的地方

超时决定一次请求等多久,重试与退避决定这次请求失败后要不要再发、隔多久再发;两者通常配合使用。熔断器处理的是持续故障:当一批请求都失败时,它会暂时停止继续调用,而不是让每个请求各自重试。

什么时候用

适合用

  • 网站读取外部天气数据时,接口偶发不可用;短暂等待后再试,有机会让页面正常显示。
  • AI 工具调用模型服务时遇到临时故障;在可接受的等待时间内尝试恢复,而不是立刻报错。
  • 后台任务从对象存储读取文件时偶尔连接中断;任务可以延后再取,并记录最终失败结果。

不适合用

  • 用户提交的表单缺少必填字段时,等待不会让数据变对;直接返回校验错误,让用户修改。
  • 账号没有访问权限时,反复请求也拿不到资源;返回权限错误,并引导用户申请权限或登录。
  • 订单已创建但响应丢失,且没有防重复机制时,直接重试可能生成两笔订单;先设计幂等处理或查询订单状态。

练一练

你做的后台每小时从外部接口读取商品汇率。接口偶尔返回服务暂时不可用,但任务必须在几分钟内结束。你会怎么处理?

让 AI 帮你做

请为后台读取外部接口的请求加入重试与退避:只重试可能暂时恢复的失败,等待时间逐次增加并加入随机偏移;限制尝试次数和总耗时,最终失败时保留错误信息。请说明哪些错误不会重试,并补上相应测试。

接下来学什么