
requests 超时必须显式设置,不设 timeout 参数会导致请求无限等待,极易引发服务阻塞、线程耗尽或响应延迟飙升。
timeout 应始终传入 tuple (connect, read)
只传单个数值(如 timeout=5)等价于 timeout=(5, 5),但连接和读取阶段失败原因不同、合理耗时也不同,混用会掩盖问题。连接超时应较短(通常 3–5 秒),用于应对 DNS 解析失败、目标不可达、防火墙拦截等;读取超时应稍长(如 10–30 秒),覆盖网络抖动、后端处理慢、大响应体传输等场景。
- 推荐写法:
requests.get(url, timeout=(3, 15)) - 连接阶段卡住 3 秒即放弃,避免空耗资源
- 读取阶段允许最多 15 秒接收完整响应,兼顾稳定性与及时性
对关键调用统一封装超时逻辑
避免在每个 requests 调用处重复写 timeout,尤其当多个接口共用同一类超时策略时。用函数封装可集中管理、便于后续调整。
- 示例封装:
def api_get(url, **kwargs):<br> return requests.get(url, timeout=(3, 15), **kwargs)
- 内部服务间调用可更激进(如
(2, 5)),对外部第三方 API 可放宽(如(5, 45)) - 结合重试时,每次重试都应带 timeout,且可考虑逐次递增读取时间
捕获超时异常并区分处理
requests 抛出的 requests.exceptions.Timeout 是 requests.exceptions.RequestException 的子类,需单独捕获,不能只靠通用异常兜底。连接超时与读取超时行为不同,建议分别响应。
立即学习“Python免费学习笔记(深入)”;
- 连接超时:大概率是网络层问题,立即失败或降级,不宜重试
- 读取超时:可能是后端临时繁忙,可有限重试(如 1–2 次),但需加退避(如指数退避)
- 代码中明确判断:
except requests.exceptions.ConnectTimeout:<br> log.error("连接失败,请检查网络或目标地址")<br>except requests.exceptions.ReadTimeout:<br> log.warning("响应过慢,触发读取超时")
生产环境务必监控超时发生频率
超时不是偶发异常,而是系统健康度的关键指标。高频连接超时指向网络或依赖服务不可用;高频读取超时可能反映下游性能恶化、慢查询未优化或突发流量冲击。
- 在请求前后打点,记录是否超时、耗时、状态码
- 将超时事件上报至监控系统(如 Prometheus + Grafana),设置告警阈值
- 定期分析超时分布:哪个接口、哪个上游、哪个时段最频繁,驱动根因改进










