背景
http是建立在TCP之上的,一次TCP连接要经过三次握手过程。当我们通过http发送请求时,如果一次http对应一个TCP,会造成TCP频繁的重建,造成资源浪费,对于这个问题,就有了http连接池,用于缓存TCP连接和请求前的公共数据,如认证证书过程等。
http连接池
http连接池缓存的是TCP连接。这个连接是针对于host的。如果要向不同的域名发送请求,缓存多个域名的连接,需要有多个连接池。
from urllib3 import HTTPConnectionPool
pool = HTTPConnectionPool('blog.csdn.net', maxsize=1)
def test():
for _ in range(5):
r = pool.request('GET', '/')
print(r.status)
- 上面示例是python模块urllib3下的http连接池使用示例,可用抓包的方式测试上面示例运行之后,建立了几次TCP连接,其实是1次。
-
maxsize
参数代表缓存的数量,默认1, 例子中5次http请求,共用同一个TCP连接。
1,如果是多线程下,多线程共用同一个pool,block参数为True时,比如有两个线程,当缓存的可用的TCP连接释放,第二个线程才会新建,也就是这两个线程用同一个TCP连接
import threading
from urllib3 import HTTPConnectionPool
pool = HTTPConnectionPool('blog.csdn.net', maxsize=1, block=True)
def test():
for _ in range(5):
r = pool.request('GET', '/a', redirect=False)
print(r.status)
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
t1.start()
t2.start()
2,block参数为False时,比如有两个线程,那么第二个线程会新建一个TCP连接,但是使用完成之后连接被销毁。连接池只会保存一个连接。
urllib3.PoolManager
连接池管理器
HTTPConnectionPool是针对host而言的,如果想向不同的host发送请求,就用到了PoolManager,用于管理多个连接池,也就是相当于多个域名的缓存。
from urllib3 import PoolManager
manager = PoolManager(num_pools=2)
manager.request('GET', 'http://www.baidu.com')
manager.request('GET', 'https://www.jianshu.com/')
manager.request('GET', 'https://www.json.cn/')
print(len(manager.pools))
print(manager.pools._container)
num_pools表示池的数量,当超过时,会存储最近的num_pools个pool
使用PoolManager的示例
import requests
s = requests.Session()
s.mount('https://', HTTPAdapter(pool_connections=1, pool_maxsize=2))
- pool_maxsize会传到
HTTPConnectionPool
控制缓存连接的数量,pool_connections
会传到PoolManager
控制Pool
的数量。 -
HTTPAdapter
属于requests
中的一个类,HTTPAdapter
类的源码中调用的是urllib3.PoolManager
和HTTPConnectionPool
,有兴趣可以查看一下源码。
网友评论