来自aiohttp
文档:
[
aiohttp.ClientSession
]封装了一个连接池(连接器实例),并且默认情况下支持keepalive。 除非您在应用程序的生存期内连接到大量未知的不同服务器,否则建议您在应用程序的生存期内使用单个会话以受益于连接池。
我几乎总是采用对任何大小或容器的URL保留单个ClientSession
实例(启用cookie和自定义连接器/适配器*)的做法,无论这些URL的种类繁多或数量多少其中有。我想知道这种方法是否有缺点。
我希望对实践中“大型,未知数量的不同服务器”的构成有一个更细致的上下文定义。下列情况下的最佳做法是什么? ClientSession
是否应该专用于每个netloc,而不是整个集合的单个实例?**是否使用单个客户端会话的决定是否仅由响应时间决定?
通常情况下,我有很多端点。每个批次的netloc是同质的,但是批次之间的netloc是不同的。例如,
urls = {
'https://aiohttp.readthedocs.io/en/stable/index.html',
'https://aiohttp.readthedocs.io/en/stable/client_reference.html',
'https://aiohttp.readthedocs.io/en/stable/web_advanced.html#aiohttp-web-middlewares',
'https://www.thesaurus.com/',
'https://www.thesaurus.com/browse/encapsulate',
'https://www.thesaurus.com/browse/connection?s=t',
'https://httpbin.org/',
'https://httpbin.org/#/HTTP_Methods',
'https://httpbin.org/status/200'
}
要在上面加上一个数字,实际上每批的长度可能为25-50。
*我现在要做的是通过将连接器实例传递到ClientSession
(aiohttp.TCPConnector(limit_per_host=10)
)来限制对任何单个主机的打开连接。
**具体来说,{'www.thesaurus.com', 'aiohttp.readthedocs.io', 'httpbin.org'}
,即set(urllib.parse.urlsplit(u).netloc for u in urls)
。
答案 0 :(得分:2)
您希望在使用专用会话时使用自己的连接器
后一种情况是文档所暗示的。假设您要连接的唯一主机数量更多(唯一主机是主机名,端口号以及是否使用SSL的唯一组合),但是正在与其中的 some 个主机联系比其他人更多。如果“大数字”> 100,则您可能必须继续为之前已连接的“频繁”主机打开新连接,因为池必须关闭它们才能为当前不在的主机创建连接游泳池。那会影响性能。
但是,如果您为“常用”主机创建了一个单独的池,则可以使这些主机连接的打开时间更长。他们不必与所有那些不经常使用的主机连接竞争来自“通用”池的免费连接。
在aiohttp中,您通过使用单独的会话来创建单独的池,然后必须定义逻辑以选择用于给定请求的会话。
为进行比较,requests
库(一个同步HTTP API)对它的处理方式略有不同,您可以在其中register separate transport adapters per url prefix。