You need to enable JavaScript to run this app. Python3 requests库失败请求重试最佳实践及实现优化
优惠活动
大模型
产品
解决方案
定价
更多

Python3 requests库失败请求重试最佳实践及实现优化

现有实现的问题梳理
  • 递归实现的固有风险:Python默认递归深度阈值约为1000,虽然当前max_retry=10的参数不会触发栈溢出,但这种用递归写重试逻辑的方式没有必要,一旦后续调整大重试上限,直接触发栈溢出报错。循环即可覆盖全部重试逻辑,更直观也没有栈深度限制。
  • 重试范围无差别触发:当前只要抛出RequestException就进入重试流程,但像401未授权、403权限不足、404资源不存在这类永久性客户端错误,重试多少次都不会成功,只会白白拉长故障时间、浪费网络请求资源。
  • 退避策略缺随机抖动:纯逐次翻倍的固定等待间隔,在大规模客户端同时发起请求的场景下,容易形成同步重试风暴,把本就处于故障状态的服务进一步打垮。
  • 异常信息丢失:重试耗尽后统一抛出通用RequestException,会掩盖根因异常类型(比如DNS解析失败、SSL证书校验失败、连接超时),排查问题时无法直接捕获、定位具体错误。
  • 重试次数边界错位:当前判断条件为retries > max_retry,实际发起的总请求次数会比设定的max_retry多1次,和函数注释描述的重试次数逻辑不匹配。
行业通用最佳实践
  • 优先复用成熟的重试能力,不从零手写逻辑:行业通用的实现方式要么用专门的重试工具库,要么直接给requests挂载内置的urllib3重试适配器,不需要自己维护递归、退避、异常判定的整套逻辑,经过大量线上场景验证的框架会规避掉绝大多数边角问题。
  • 只对临时性错误做重试:仅针对连接超时、读超时、5xx服务端错误、网络抖动导致的连接重置这类大概率重试后可成功的场景触发重试,遇到永久性客户端错误直接抛出,不进入重试流程。
  • 指数退避加随机抖动:逐次翻倍的等待间隔思路是完全正确的,只需要在等待时间里加入小范围随机偏移,打散不同客户端的重试时间点,避免同步冲击服务端。
  • 日志替换print输出:重试过程的状态信息要用标准日志模块输出,方便生产环境统一采集、检索问题,直接用print输出的日志在多数线上环境无法正常留存。
  • 重试耗尽后抛出原始异常:不要把所有异常都包装成通用的RequestException,保留最开始抛出的根因异常类型,方便上层业务针对不同错误做差异化处理。
可直接复用的优化参考实现
import time
import logging
import requests
from requests.exceptions import (
    RequestException,
    ConnectionError,
    Timeout,
    HTTPError
)

# 初始化日志配置
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 定义可触发重试的异常类型
RETRYABLE_EXCEPTIONS = (ConnectionError, Timeout)

def get_request(url, max_retry=10, **kwargs):
    wait_interval = 0.005
    last_error = None
    # 用循环实现重试,替代递归
    for _ in range(max_retry):
        try:
            response = requests.get(url, **kwargs)
            response.raise_for_status()
            # 请求成功直接返回响应对象
            return response
        except RequestException as exc:
            last_error = exc
            # 非可重试类型的异常直接抛出,不进入重试
            if not isinstance(exc, RETRYABLE_EXCEPTIONS):
                raise exc from last_error
            logger.info("请求失败: %s,%s秒后触发重试", str(exc), round(wait_interval, 2))
            time.sleep(wait_interval)
            # 退避翻倍,同时加入随机抖动打散重试时间
            wait_interval = wait_interval * 2 + (time.time() % 0.1)
    # 重试耗尽,抛出留存的原始异常
    raise last_error

内容的提问来源于stack exchange,提问作者irahorecka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 12:27:05