Python HTTP 连接复用实现方法

8次阅读

Python HTTP 连接复用实现方法

Python 中实现 HTTP 连接复用,核心是重用底层 TCP 连接,避免每次请求都经历 DNS 查询、TCP 握手和 TLS 协商,从而显著提升高频请求场景下的性能。关键在于使用支持连接池的 HTTP 客户端,并正确配置生命周期管理。

使用 requests + urllib3 连接池(最常用)

requests 库默认基于 urllib3,后者内置了线程安全的连接池(PoolManager)。只要复用同一个 Session 实例,它就会自动复用连接。

  • 创建一个全局或长生命周期的 requests.Session() 对象,而不是每次用 requests.get() 临时发起请求
  • 可显式配置连接池大小和超时:
    session = requests.Session()<br> adapter = requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=20, max_retries=3)<br> session.mount("http://", adapter)<br> session.mount("https://", adapter)

  • 注意:默认情况下,urllib3 会复用满足 Connection: keep-alive 响应头且未关闭的连接;服务端也需支持并返回该头

手动管理 urllib3 PoolManager(更底层、更灵活)

绕过 requests,直接使用 urllib3 的 PoolManagerProxyManager,适合需要精细控制连接行为(如自定义路由、证书验证逻辑)的场景。

  • manager = urllib3.PoolManager(num_pools=10, maxsize=20, block=True) 创建连接池
  • 调用 manager.request("GET", "https://api.example.com") 时,自动从池中获取空闲连接或新建连接
  • 连接在响应读取完毕、且响应头声明 keep-alive 时,会被放回池中供后续复用
  • 可通过 manager.clear() 主动清空连接池(例如更换代理或证书后)

使用 httpx(现代异步 / 同步双模选择)

httpx 是 requests 的现代化替代品,原生支持连接池(同步与异步共用同一套池机制),且对 HTTP/2 和异步请求有更好支持。

立即学习 Python 免费学习笔记(深入)”;

  • 同步用法:with httpx.Client() as client: response = client.get("https://……") —— Client 实例内部维护连接池
  • 异步用法:async with httpx.AsyncClient() as client: 同样复用连接,适合高并发 I/O 场景
  • 可配置 limits=httpx.Limits(max_connections=100, max_keepalive_connections=20, keepalive_expiry=60.0)
  • 注意:HTTP/2 默认启用流复用,单个 TCP 连接可并发处理多个请求,进一步减少连接开销

注意事项与常见陷阱

连接复用不是“开了就一定生效”,需配合服务端行为与客户端配置协同工作。

  • 服务端必须返回 Connection: keep-alive(HTTP/1.1 默认行为,但某些 Nginx 或 CDN 可能禁用)
  • 避免在请求头中手动设置 Connection: close,这会强制关闭连接
  • 长时间空闲连接可能被中间设备(如负载均衡器、防火墙)主动断开,建议设置合理的 keepalive_expiry 或启用连接健康检查
  • 多线程 / 多进程环境下,每个线程应使用独立 Session,或确保 Session 是线程局部的;multiprocessing 中不能共享 Session 实例

text=ZqhQzanResources