超时和重试,配错了比不配还危险

举报
yd_252271337 发表于 2026/11/10 10:44:17 2026/11/10
【摘要】 # 超时和重试,配错了比不配还危险有次线上服务突然大面积超时,查到最后,根子不在某个接口慢,而在我们自己的重试逻辑:一个下游接口抖动,调用方疯狂重试,把下游彻底压垮,然后雪崩到整个链路。那次之后,我把超时和重试的配置重新理了一遍。## 超时不是越长越安全很多人怕超时,就把超时设得很大,觉得「多等等总能返回」。问题是,等待也是有代价的:线程被占着、连接被占着,下游越慢,上游堆积越多。超时应该根...

# 超时和重试,配错了比不配还危险

有次线上服务突然大面积超时,查到最后,根子不在某个接口慢,而在我们自己的重试逻辑:一个下游接口抖动,调用方疯狂重试,把下游彻底压垮,然后雪崩到整个链路。那次之后,我把超时和重试的配置重新理了一遍。

## 超时不是越长越安全

很多人怕超时,就把超时设得很大,觉得「多等等总能返回」。问题是,等待也是有代价的:线程被占着、连接被占着,下游越慢,上游堆积越多。

超时应该根据链路的实际耗时来定。一个接口 P99 是 200ms,超时设 2 秒就偏大了。合理的做法是:先看监控里的 P99,再留一点余量,比如 P99 的 1.5 到 2 倍。

```python
import requests

try:
    resp = requests.get(url, timeout=(1, 3))  # 连接 1s,读取 3s
except requests.Timeout:
    handle_timeout()
```

注意连接超时和读取超时要分开设。连接超时短一点,读取超时按业务定。

## 重试的三个大坑

**坑一:重试非幂等操作**

下单、支付这类操作,重试一次可能就多扣一次钱。重试之前先问:这个操作重复执行安全吗?不安全的话,要么别重试,要么用幂等键去重。

**坑二:没有退避**

失败后立刻重试,间隔 0,下游还没缓过来又被砸一次。正确做法是指数退避,间隔逐渐拉长。

**坑三:重试放大**

A 调 B,B 调 C,每层都重试 3 次。C 挂一次,实际收到 3×3×3 = 27 次请求。链路越长,放大越可怕。要么只在最外层重试,要么严格控制层数和次数。

## 退避加抖动

```python
import time, random

def call_with_retry(fn, max_retry=3):
    for attempt in range(max_retry):
        try:
            return fn()
        except TransientError:
            if attempt == max_retry - 1:
                raise
            base = 0.2 * (2 ** attempt)
            sleep = base + random.uniform(0, base)  # 加抖动
            time.sleep(sleep)
```

加抖动是为了避免大量请求在同一时刻一起重试,形成新的尖峰。

## 重试要区分错误类型

不是所有错误都值得重试:

- 网络超时、连接失败:可以重试
- 5xx:视情况,幂等的可以
- 4xx(参数错、鉴权失败):重试没用,别浪费

```python
if isinstance(e, (Timeout, ConnectionError)):
    retry()
elif 500 <= status < 600:
    retry()
else:
    raise  # 4xx 直接抛
```

## 熔断是重试的搭档

重试解决偶发失败,熔断解决持续故障。下游已经挂了,还一直重试,只会加重问题。

熔断的思路:连续失败达到阈值,直接快速失败一段时间,等下游恢复再放量。常用的库有 Resilience4j、Sentinel。

重试 + 熔断 + 超时,这三个要一起配,单配一个都不完整。

## 几个实践建议

- 超时按 P99 的 1.5~2 倍设,别拍脑袋
- 重试只对幂等操作和瞬时错误
- 一定要有退避和抖动
- 重试次数别太多,2~3 次足够
- 链路长时,限制重试层数
- 配熔断,防止持续故障放大

## 小结

超时和重试是保护系统的手段,但配错了会变成放大器。核心是三件事:超时按实际耗时定、重试只对幂等和瞬时错误、退避加抖动防风暴。再加上熔断兜底,才是一套完整的容错。

别等被打挂了才想起来配这些。平时多看一眼监控,比事故后复盘便宜得多。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。