复用 requests.Session() 能显著提升高频 HTTP 请求性能,主要体现在同一域名的连续请求中,通过复用 TCP/TLS 连接减少握手开销,实测耗时可降30%–70%;但跨域名、服务端关闭连接或未关闭 Session 时可能无效甚至更慢。

复用 requests.Session() 确实能显著提升高频 HTTP 请求的性能,但效果高度依赖使用场景——不是所有情况都有效,也并非“用了就快”。核心收益来自连接复用(HTTP/1.1 Keep-Alive)和请求预配置,而非 Session 本身有魔法。
真实性能提升主要体现在哪些场景
当连续发起多个请求到同一域名(含端口、协议)时,Session 复用底层 urllib3 连接池,避免重复 TCP 握手、TLS 协商和连接建立开销。实测中,对同一 host 的 100 次请求,相比每次新建 Session,总耗时可减少 30%–70%,尤其在网络延迟高或 TLS 开销大(如 HTTPS)时更明显。
- 同域名批量请求:如调用同一 API 的分页数据、轮询状态接口
- 短连接密集型任务:如爬虫抓取同一站点的多个页面
- 服务端支持 Keep-Alive 且未主动关闭连接(常见于主流 Web 服务器)
关键限制条件:什么情况下不提速甚至更慢
Session 的连接池不会自动优化跨域名请求,也不保证连接永远复用。以下情况会失效或引入额外负担:
- 请求目标域名不同:每个新 host 会分配独立连接池,无法共享;频繁切换域名时,Session 反而因维护多个空闲连接增加内存开销
- 服务端返回 Connection: close:即使用了 Session,每次响应后连接仍被关闭,下一次请求仍需新建连接
- 超时或异常中断连接:urllib3 会将失效连接从池中剔除,下次请求触发重连,此时复用失效
-
未显式关闭 Session:长期运行程序若不调用
session.close(),空闲连接可能堆积,占用文件描述符(尤其在高并发、短生命周期脚本中)
如何确认是否真正复用了连接
可通过日志或底层机制验证实际行为:
- 启用 urllib3 调试日志:
import logging; logging.basicConfig(level=logging.DEBUG),观察是否有Starting new HTTPS connection或Resetting dropped connection日志 - 检查连接池状态:
session.adapters['https://'].poolmanager.connection_pool_kw查看池大小与当前空闲连接数 - 用 Wireshark 或
tcpdump抓包,确认 TCP 连接是否复用(相同源/目的 IP+端口上承载多个 HTTP 请求)
最佳实践建议
不是“所有请求都该套个 Session”,而是按粒度合理复用:
- 单次脚本中对同一服务的多次调用:用一个 Session,用完
close() - 长周期服务(如 Flask 后端调用外部 API):全局复用一个 Session 实例(注意线程安全,urllib3 默认线程安全)
- 混合域名请求:按域名分组,为每组创建专用 Session,避免池污染
- 显式控制连接池参数(谨慎调整):
requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=20),避免默认值(10/10)在高并发下成为瓶颈











