http.client.RemoteDisconnected报错:是重试耗尽还是需额外错误处理?
问题描述
我使用requests库编写了一段从API获取响应并将结果存入数据库的代码,为了自定义BACKOFF_MAX变量,我实现了RetryRequest类。代码示例如下:
from requests import Session from requests.adapters import HTTPAdapter, Retry from time import sleep class RetryRequest(Retry): def __init__(self, backoff_max: int, **kwargs): super().__init__(**kwargs) self.BACKOFF_MAX = backoff_max session = Session() retries_spec = RetryRequest( total=25, backoff_factor=0.25, backoff_max=128, ) session.mount("https://", HTTPAdapter(max_retries=retries_spec)) headers = {"User-Agent": "*", "Referer": None} session.headers.update(headers) while True: response = session.get(<url>) # load response into database sleep(60)
这段代码循环执行数百次均正常,但偶尔会抛出以下错误:
http.client.RemoteDisconnected: Remote end closed connection without response
请问这是重试次数耗尽导致的,还是需要添加额外的错误处理逻辑?
问题分析与解决方案
错误本质:这个异常和重试次数耗尽无关。requests默认的
Retry机制不会自动捕获RemoteDisconnected异常——它默认只针对连接超时、DNS失败、特定5xx状态码等场景触发重试,而服务器主动断开连接且无响应的情况不在默认重试范围内,所以遇到该异常时会直接抛出,不会走你设置的25次重试流程。必须添加额外错误处理:
- 扩展重试机制的异常覆盖范围:
你可以通过重写RetryRequest类的retry_on_exception方法,将RemoteDisconnected加入可重试的异常列表,让重试机制自动处理这类错误。同时建议明确指定允许重试的HTTP方法和需要重试的状态码,避免不必要的重试。
修改后的代码示例:from requests import Session from requests.adapters import HTTPAdapter, Retry from time import sleep from http.client import RemoteDisconnected class RetryRequest(Retry): def __init__(self, backoff_max: int, **kwargs): super().__init__(**kwargs) self.BACKOFF_MAX = backoff_max def retry_on_exception(self, exception): # 新增对RemoteDisconnected的重试判断 if isinstance(exception, RemoteDisconnected): return True # 保留原有的重试异常判断逻辑 return super().retry_on_exception(exception) session = Session() retries_spec = RetryRequest( total=25, backoff_factor=0.25, backoff_max=128, allowed_methods=["GET"], # 明确允许重试的方法 status_forcelist=[500, 502, 503, 504], # 指定需要重试的服务器错误状态码 ) session.mount("https://", HTTPAdapter(max_retries=retries_spec)) headers = {"User-Agent": "*", "Referer": None} session.headers.update(headers) while True: try: response = session.get(<url>) response.raise_for_status() # 触发HTTP状态码异常,让重试机制处理 # load response into database except Exception as e: # 可选:添加日志记录异常信息 print(f"请求出错: {str(e)}") sleep(60) - 增加全局异常捕获:
在循环的请求逻辑外层包裹try-except块,即使重试机制未覆盖到某些异常,也能捕获并避免程序直接崩溃,同时可以根据需求添加自定义的等待、重试逻辑。
- 扩展重试机制的异常覆盖范围:
内容的提问来源于stack exchange,提问作者Jossy
相关产品推荐
相关产品推荐

