requests 库超时设置应同时配置连接超时和读取超时,使用元组形式传入 timeout 参数。生产环境严禁将 timeout 设为 None,否则可能导致程序无限挂起。
先说结论:明确区分连接与读取超时,根据业务容忍度设定阈值,避免默认无限等待。
- 适合:高并发爬虫或 API 调用场景
- 先准备:评估目标服务平均响应时间和网络波动范围
- 验收:监控 Timeout 异常占比及重试成功率
快速处理思路
代码中显式传入 timeout 元组,不要依赖默认值。示例配置如下:
import requests
try:
r = requests.get('https://example.com', timeout=(3.0, 10.0))
except requests.exceptions.Timeout:
# 处理超时逻辑
pass
为什么会这样
超时设置的核心是防止客户端资源被慢速服务端占用。requests 库默认 timeout 为 None,意味着没有超时限制。
连接超时控制握手建立时间,读取超时控制数据接收间隔。不设置会导致线程阻塞,影响系统整体吞吐量。
分步处理
第一步:确定网络环境基准。测试目标接口在正常负载下的响应耗时,记录 P95 数值。
第二步:配置元组参数。将 timeout 设置为 (connect_timeout, read_timeout),读取超时通常大于连接超时。
第三步:添加异常捕获。专门捕获 requests.exceptions.Timeout,区分于其他网络错误。
第四步:实施重试机制。配合 urllib3 的 Retry 类,在超时后执行有限次重试。
怎么验证是否生效
查看应用日志中是否出现 ReadTimeout 或 ConnectTimeout 异常记录。统计单位时间内超时错误占比,确认是否在预期范围内。
通过压测工具模拟高负载,观察程序是否出现线程堆积或无响应现象。
常见坑
误区一:将 timeout 理解为总耗时。实际是读取数据块之间的间隔超时,而非整个请求完成的总时间。
误区二:全局设置忽略差异。不同接口响应速度不同,避免对所有 URL 使用同一超时值。
误区三:超时后不释放连接。确保异常处理中包含连接关闭或会话复用管理。
常见问题
requests 默认超时时间是多少?
默认值为 None,即无限等待。官方文档建议生产环境必须显式设置超时值。
连接超时和读取超时有什么区别?
连接超时指建立 TCP 握手的时间,读取超时指服务器发送数据之间的间隔时间。
如何设置全局超时?
requests 不支持直接全局设置,需封装 Session 对象或在每次请求中统一传入参数。
参考来源
Requests 官方文档 - Timeouts: https://requests.readthedocs.io/en/latest/user/advanced/#timeouts