📢 欢迎来到万事技术论坛!本站仅讨论合法编程技术话题,严禁外挂/作弊/黑产/盗版内容,违者封号。

精华接口超时与重试:别让重试把下游打挂

lin_dev 活跃会员

下游抖动时加重试很自然,但没有策略的重试就是 DDoS。

重试风暴是怎么发生的

下游 A 变慢 → 上游 1000 个请求全部超时 → 每个都重试 3 次 → A 瞬间承受 3000 次请求 → 更慢 → 更多超时……雪崩就这么来的。

四个必须有

1. 指数退避 + 抖动

import random, time

def backoff(n, base=0.5, cap=8):
    # 0.5s, 1s, 2s, 4s, 8s... 加上随机抖动打散重试时刻
    return min(cap, base * 2 ** n) * (0.5 + random.random() / 2)

抖动(jitter)很关键:不抖的话所有客户端会在同一秒集体重试,形成尖峰。

2. 重试预算:重试次数不能超过总请求的一定比例(如 10%),超了就不重试。这样即使下游全挂,放大倍数也有限。

3. 只重试可重试的错误:超时、5xx、连接重置可以重试;400 参数错误、401 鉴权失败重试一万次也是失败,纯属浪费。

4. 熔断:连续失败到阈值直接短路,一段时间内请求立刻失败不再打下游,给下游喘息时间。半开状态试探性放行。

超时时间怎么定

一个反直觉的原则:下游超时必须小于上游超时。

用户 → 网关(3s) → 订单服务(2s) → 库存服务(1s)

如果库存 5s、订单 2s,订单早就放弃了,库存还在傻算,白白占着资源。

Python 里怎么写

import httpx

transport = httpx.HTTPTransport(retries=2)
with httpx.Client(transport=transport, timeout=httpx.Timeout(2.0, connect=0.5)) as c:
    c.get(url)

注意 connect 超时要单独设短一点(0.5s),connect 阶段卡住通常意味着网络或对端已经不正常了。

楼主 · 2026-09-28 13:21 · 浏览 2
登录 后即可参与回复。