Python 网络请求重试与退避策略实战:让自动化脚本更健壮

举报
yd_298518110 发表于 2026/10/22 21:47:42 2026/10/22
【摘要】 在日常开发和自动化运维中,网络请求失败是家常便饭:接口抖动、网关超时、短暂的网络分区,都会让一次本可成功的调用直接报错退出。一个健壮的脚本不应该在第一次失败时就放弃,而应该具备“重试 + 退避”的能力。一、为什么需要退避简单的固定间隔重试(比如每次失 3 秒再试)在服务端故障时可能加剧压力——大量客户端同时重试会形成“重试风暴”。指数退避让等待时间随失败次数指数增长:1 秒、2 秒、4 秒、...

在日常开发和自动化运维中,网络请求失败是家常便饭:接口抖动、网关超时、短暂的网络分区,都会让一次本可成功的调用直接报错退出。一个健壮的脚本不应该在第一次失败时就放弃,而应该具备“重试 + 退避”的能力。


一、为什么需要退避

简单的固定间隔重试(比如每次失 3 秒再试)在服务端故障时可能加剧压力——大量客户端同时重试会形成“重试风暴”。指数退避让等待时间随失败次数指数增长:1 秒、2 秒、4 秒、8 秒……再加上随机抖动,把重试请求均匀散开,既提高成功率,又避免压垮服务端。


二、一个可复用的重试装饰器

下面是一个 Python 重试装饰器,支持指定最大尝试次数、基础延迟和可重试的异常类型:

import time, random, functools

def retry(max_attempts=5, base_delay=1.0, exceptions=(Exception,)):    def deco(fn):        @functools.wraps(fn)        def wrapper(*args, kwargs):            for attempt in range(1, max_attempts + 1):                try:                    return fn(*args, *kwargs)                except exceptions as e:                    if attempt == max_attempts:                        raise                    delay = base_delay  (2  (attempt - 1)) + random.uniform(0, 1)                    print(f"第 {attempt} 次失败:{e},{delay:.1f}s 后重试")                    time.sleep(delay)        return wrapper    return deco


三、 requests 使用

把网络请求包一层即可拥有重试能力:import requests

@retry(max_attempts=4, base_delay=1.0, exceptions=(requests.RequestException,))def fetch(url, timeout=10):    resp = requests.get(url, timeout=timeout)    resp.raise_for_status






配合
















通用的败都等

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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