赞
踩
requests是python3里面处理http网络库,目前支持http1.*,封装了urllib3,session默认是http1.1,
所以支持长连接,同时 requests.Session回话支持连接池,下面我们主要讲解下连接池的实现。
import requests
session = requests.session() # 创建一个会话
res = session.get("http://www.baidu.com") # 请求百度
print(res.status, res.text) # 打印响应结果
上面如果就单个请求没啥,但是请求并发多了的时候,如果每次都创建连接,端口连接是不是很费力,
那session 底层都做了啥,requests.session()会创建Session类的实例(session),session对象有如下应映射关系:
session ---->adapters---->poolmanager---->pools---->pool---->connections,下面我们具体讲讲这个映射链,
1、session在创建的时候会调用default_headers函数,default_headers函数代码如下:
def default_headers():
"""
:rtype: requests.structures.CaseInsensitiveDict
"""
return CaseInsensitiveDict({
'User-Agent': default_user_agent(),
'Accept-Encoding': ', '.join(('gzip', 'deflate')),
'Accept': '*/*',
'Connection': 'keep-alive',
})
从代码可以看出http头里面有Connection,并且为keep-alive,所以在使用会话的时候请求结束不会释放掉连接,
当然这个还要看服务端,如果服务端不主动断开,socket连接是不会断开的。
2、session会话有个adapters属性是一个排序字典,放了两个适配器,一个用于https,一个用于http,
适配器是requests.adapters.HTTPAdapter类的实例。
3、每个适配器有一个连接池管理对象poolmanager,poolmanager对象是urllib3.poolmanager.PoolManager类的实例,
4、连接池管理对象有个pools属性,pools是一个map,urllib3._collections.RecentlyUsedContainer的实例,
存放了多个连接池(pool),pools的key由url的scheme、host、port等字段组成。
5、连接池pool是urllib3.connectionpool.HTTPConnectionPool或者urllib3.connectionpool.HTTPSConnectionPool的
实例,连接池默认大小是10个,这也说明对于一个网站的请求默认创建10个连接。
6、连接池pool有个队列属性,队列大小默认为10,存放连接,请求到来时,从队列里面获取连接,处理完请求后,又把连接放入队列里面,
这样保证了一个连接不会被多个请求同时共用。
最后可以发现,一个会话(session)映射两个适配器(adapter),一个适配器(adapter)映射一个连接池管理器(poolmanager),
一个连接池管理器(poolmanager)映射多个连接池(pool),一个连接池(pool)存放着多个连接。会话(session)会根据请求
url的scheme、host、port等字段hash到连接池(pool),然后从连接池(pool)里面获取连接,处理完请求后在把连接放入
连接池(pool)。上面涉及到了http1.1的长连接,其实和http2有个明显的区别,http2.0一个socket连接可以供多个请求同时共用,可以参考https://www.cnblogs.com/heluan/p/8620312.html。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。