You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在urllib3的Retry类中使用固定重试间隔而非指数退避?

urllib3自定义Retry类固定重试间隔参数不生效的解决方法

问题场景

想要在urllib3的Retry类中使用固定重试间隔而非指数退避,于是封装了LoggingRetry子类,初始化时指定delay_between_retries=2,但实际重试时该参数始终是默认值0,backoff_factor参数却能正常生效。

问题原因

urllib3在处理重试逻辑时,每次重试都会调用Retry类的new()方法生成新的Retry实例,而原代码没有重写这个方法,导致自定义的delay_between_retries属性无法传递给新实例,新实例会使用该参数的默认值0。

解决方案

重写LoggingRetry类的new()方法,在创建新实例时将当前实例的delay_between_retries属性传递进去,确保每次重试时该参数都能保留初始设置的值。

修改后的完整代码:

import time
import urllib3
from urllib3.util.retry import Retry
from urllib3.exceptions import MaxRetryError
from requests.exceptions import HTTPError
import traceback

# 带日志的自定义重试策略
class LoggingRetry(Retry):
    def __init__(self, delay_between_retries=0, *args, **kwargs):
        print(f"初始化LoggingRetry,delay_between_retries={delay_between_retries}")
        self.delay_between_retries = delay_between_retries
        super().__init__(*args, **kwargs)

    def sleep(self, response=None):
        backoff = self.get_backoff_time()
        total_sleep_time = self.delay_between_retries + backoff
        print(f"LoggingRetry 睡眠 - delay_between_retries: {self.delay_between_retries}, 退避时间: {backoff}")
        time.sleep(total_sleep_time)

    # 重写new方法,传递自定义参数
    def new(self, **kwargs):
        # 调用父类new方法生成新实例,同步自定义参数
        new_retry = super().new(**kwargs)
        new_retry.delay_between_retries = self.delay_between_retries
        return new_retry

class MyClient:
    def __init__(self, total_tries=3, delay_between_retries=0, backoff_factor=0):
        self.total_tries = total_tries
        self.delay_between_retries = delay_between_retries
        self.backoff_factor = backoff_factor

        # 初始化自定义重试策略
        self.retry_strategy = LoggingRetry(
            total=self.total_tries,
            status_forcelist=[202],
            backoff_factor=self.backoff_factor,
            delay_between_retries=self.delay_between_retries,
            raise_on_status=False,
            allowed_methods=frozenset(['GET'])
        )
        
        # 初始化带重试策略的HTTP客户端
        self.http = urllib3.PoolManager(retries=self.retry_strategy, maxsize=4, block=True)

    
    def request_data(self, url):    
        try:
            response = self.http.request('GET', url,)
            return response
        except MaxRetryError as me:
            print(f"达到最大重试次数: {me}")
        except HTTPError as he:
            print(f"HTTP错误发生: {he}")
            traceback.print_exc()
        except Exception as e:
            print(f"未知错误发生: {e}")
            traceback.print_exc()

MyClient(delay_between_retries=2, backoff_factor=0).request_data(url='http://0.0.0.202/')

验证效果

运行修改后的代码,每次重试时会打印出delay_between_retries: 2,说明固定间隔参数已生效,每次重试会睡眠2秒(因backoff_factor=0,总睡眠时长等于固定间隔)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 07:16:17