Python的requests库默认情况下不明确开启HTTP Keep-Alive特性,但这并不意味着它完全不支持连接复用。实际上,大多数现代HTTP库和Web服务器都隐式支持Keep-Alive,这是一种HTTP协议特性,允许在同一个TCP连接上发送多个请求,从而减少建立和关闭连接的开销。
在requests中,连接是否保持活动状态主要依赖于底层的HTTP库(通常是urllib3)以及与之通信的服务器的支持情况。默认配置下,urllib3会遵循服务器的Keep-Alive指示,如果服务器表明支持Keep-Alive,那么连接会在一段时间内保持打开状态,供后续请求复用,直到达到某个超时时间或者达到最大连接数限制。
虽然requests本身不直接提供控制Keep-Alive行为的选项,但你可以在创建Session对象时,通过自定义TransportAdapter来间接调整与Keep-Alive相关的超时和重用策略,从而影响连接的复用行为。例如,可以通过调整连接池的大小来影响连接的复用程度。
简单来说,requests默认情况下能利用Keep-Alive特性实现一定程度的连接复用,但具体的复用策略和效率更多地依赖于网络环境、服务器配置以及请求的具体情况。如果你需要更细粒度的控制,可以通过更高级的配置来调整这些行为。
写了一个代码的对比测试, 测试结果在后面
代码如下
import time import requests from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry # 创建一个带有重试策略和连接池设置的自定义 HTTPAdapter adapter = HTTPAdapter( pool_connections=10, # 连接池中的最大连接数 pool_maxsize=10, # 连接池中的最大连接数 max_retries=Retry( # 设置重试策略 total=3, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504] ) ) # 创建一个 Session 并挂载自定义的 HTTPAdapter session = requests.Session() session.mount('https://', adapter) session.mount('http://', adapter) # 使用http连接池, keepalive 复用连接 for i in range(5): t1 = time.time() response = session.get('https://httpbin.org/get') print(f"Response: {response.status_code}") t2 = time.time() print(f"第{i} 次请求, 使用session 连接池, time use: ", int(1000*(t2-t1))) # 使用普通请求, 不用连接池 for i in range(5): t1 = time.time() response = requests.get('https://httpbin.org/get') print(f"Response: {response.status_code}") t2 = time.time() print(f"第{i} 次请求, 不适用连接池, time use: ", int(1000*(t2-t1)))
测试结果
$./venv/bin/python 1.py Response: 200 第0 次请求, 使用session 连接池, time use: 945 Response: 200 第1 次请求, 使用session 连接池, time use: 553 Response: 200 第2 次请求, 使用session 连接池, time use: 215 Response: 200 第3 次请求, 使用session 连接池, time use: 216 Response: 200 第4 次请求, 使用session 连接池, time use: 216 Response: 200 第0 次请求, 不适用连接池, time use: 1356 Response: 200 第1 次请求, 不适用连接池, time use: 2026 Response: 200 第2 次请求, 不适用连接池, time use: 1078 Response: 200 第3 次请求, 不适用连接池, time use: 1114 Response: 200 第4 次请求, 不适用连接池, time use: 869
还有一个更简单的写法
在Python的requests库中,默认情况下,并没有开启keep-alive效果。这意味着每次发起请求时,都会创建一个新的TCP连接。
然而,requests库确实支持连接复用功能。你可以通过设置session来实现
简化后的代码如下:
import time import requests # 创建一个 Session 并挂载自定义的 HTTPAdapter session = requests.Session() # 使用http连接池, keepalive 复用连接 for i in range(5): t1 = time.time() response = session.get('https://httpbin.org/get') print(f"Response: {response.status_code}") t2 = time.time() print(f"第{i} 次请求, 使用session 连接池, time use: ", int(1000*(t2-t1))) # 使用普通请求, 不用连接池 for i in range(5): t1 = time.time() response = requests.get('https://httpbin.org/get') print(f"Response: {response.status_code}") t2 = time.time() print(f"第{i} 次请求, 不适用连接池, time use: ", int(1000*(t2-t1)))
测试结果如下
$./venv/bin/python 1.py Response: 200 第0 次请求, 使用session 连接池, time use: 869 Response: 200 第1 次请求, 使用session 连接池, time use: 332 Response: 200 第2 次请求, 使用session 连接池, time use: 218 Response: 200 第3 次请求, 使用session 连接池, time use: 227 Response: 200 第4 次请求, 使用session 连接池, time use: 217 Response: 200 第0 次请求, 不适用连接池, time use: 858 Response: 200 第1 次请求, 不适用连接池, time use: 874 Response: 200 第2 次请求, 不适用连接池, time use: 880 Response: 200 第3 次请求, 不适用连接池, time use: 865 Response: 200 第4 次请求, 不适用连接池, time use: 1855