Python中Session.request()间隔调用API出现连接中断问题
问题分析与解决
可能的原因
- 连接池连接过期:requests的Session会复用TCP连接以提升性能,但如果服务器设置了闲置连接超时(比如5分钟),当连接闲置超过这个时间,服务器会主动关闭连接。而requests的连接池不会主动检测连接是否有效,再次复用该连接时就会触发"Remote disconnected"错误。Postman默认会在请求前自动处理失效连接,或者每次请求新建连接,所以不会出现这个问题。
- 自定义Session的方法实现错误:你提供的代码中
__request方法存在明显问题:- 方法定义缺少
self参数,导致调用时无法访问实例属性; - 调用
self.request时参数顺序错误,requests的request方法签名是request(method, url, **kwargs),你错误地将headers作为第一个参数传入,且未正确使用关键字参数传递参数。
- 方法定义缺少
- 缺少连接异常的重试机制:Postman默认会对连接类异常进行重试,而你的代码仅捕获异常并打印,没有重试逻辑,遇到一次性连接失败时无法自动恢复。
解决办法
1. 修复自定义Session的方法实现
首先修正request方法的定义,确保符合requests的规范:
from requests.sessions import Session as _Session class Session(_Session): def request(self, method, url, **kwargs): try: # 调用父类的request方法,保留原有逻辑 response = super().request(method, url, **kwargs) return response except Exception as e: print(f"请求异常: {str(e)}") # 可选择重新抛出异常,让上层处理 raise
2. 处理连接池失效连接
通过添加HTTP适配器,让requests自动重试失效的连接:
from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 初始化自定义Session session = Session() # 配置重试策略:针对连接异常、服务器错误进行重试 retry_strategy = Retry( total=3, # 总重试次数 backoff_factor=1, # 重试间隔时间(1秒、2秒、4秒...) status_forcelist=[429, 500, 502, 503, 504], # 需要重试的状态码 allowed_methods=["GET", "POST"], # 允许重试的请求方法 retry_on_connection_errors=True # 针对连接异常进行重试 ) # 挂载适配器到Session adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("https://", adapter) session.mount("http://", adapter)
3. 可选:禁用连接复用(不推荐)
如果不需要连接复用的性能优势,可以在请求中添加Connection: close头,强制每次请求新建连接:
# 在每次请求时添加headers response = session.request("GET", "https://api.example.com", headers={"Connection": "close"})
内容的提问来源于stack exchange,提问作者Keiru Dev
相关产品推荐
相关产品推荐

