指数退避

Exponential Backoff

指数退避是 API 请求失败后逐步延长重试等待时间的策略,能有效避免在 429 限流或服务故障时形成重试风暴。

详细解释

指数退避(Exponential Backoff) 是处理 API 重试的黄金标准算法。简单说:第一次失败等 1 秒,第二次等 2 秒,第三次 4 秒,第四次 8 秒…… 每失败一次,等待时间翻倍,指数增长。

为什么必须用指数退避?想象一个服务端只是短暂抖动(100ms),你发了 1000 个并发请求,每个请求失败后立刻重试 3 次——瞬时请求量会从 1000 变成 4000,反而把服务端彻底压垮。这就叫”重试风暴”,指数退避就是为了防这个。

实现伪代码

import time
import random

def call_with_backoff(api_func, max_retries=5, base_delay=1.0):
    for attempt in range(max_retries):
        try:
            return api_func()
        except HTTP429 as e:
            if attempt == max_retries - 1:
                raise
            # 优先用服务器给的 retry-after
            delay = e.retry_after or (base_delay * (2 ** attempt))
            # + 随机抖动,避免雪崩
            delay += random.uniform(0, delay * 0.3)
            time.sleep(delay)

加不加抖动(Jitter)?

一定要加。“纯”指数退避会让 N 个并发请求精确地在同一秒再次同时出击(又一次形成同步风暴)。加上 random.uniform(0, 0.3×delay) 的抖动,把每个请求的重试时间错开,服务端的负载能被削成一半甚至更多。

唯元智创(Weimeta)的 Python/Node SDK 开箱即用支持指数退避 + 抖动 + retry-after 头优先策略,可通过 max_retries 参数配置。

常见问题

500 错误也用指数退避吗?
对临时故障(503、502、偶发 500)可用,但重试次数要少(2–3 次);对 4xx(除 429/408),尤其是 401/403,不要重试——你再等 100 年鉴权也不会变对。