何时应该为请求使用单个会话实例?

4
从文档中:

[一个]封装了一个连接池(连接器实例),并默认支持保活。 除非您在应用程序的生命周期内连接到大量不同的服务器,否则建议您使用单个会话来受益于连接池。

我几乎总是使用保持单个ClientSession实例的做法(启用cookie和自定义连接器/适配器*),无论URL的大小或容器如何,无论这些URL有多么异构或它们的数量有多少。 我想知道这种方法是否存在缺点。

我希望对实践中“大量不同服务器”的概念有更精细、具体的定义。 对于下面提出的情况,最佳实践是什么? 是否应该为每个netloc专用一个ClientSession,而不是整个集合的单个实例**? 是否决定使用单个客户端会话完全取决于响应时间?

通常情况下,我有“批次”终点;每个批次的netloc是同质的,但批次之间的netlocs是不同的。 例如,

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'
}

具体来说,我现在所做的是通过传递连接器实例到ClientSession中,限制对任何单个主机的开放连接,其中aiohttp.TCPConnector(limit_per_host = 10)


要给它一个数字,在现实中,每个批次可能长度为25-50。

**具体而言,{'www.thesaurus.com','aiohttp.readthedocs.io','httpbin.org'}set(urllib.parse.urlsplit(u).netloc for u in urls)

1个回答

4
当您需要自定义连接器参数来设置一组连接时(例如更改每个主机的限制、更改SSL配置或设置不同的超时时间)时,您应该使用具有自己连接器的专用会话。当默认的100个连接限制用尽时,缓存到现有主机的连接很可能已经被重复使用或仍然处于打开状态。这是文档所提示的后一种情况。假设您有更多要连接的唯一主机(其中唯一主机是主机名、端口号和是否使用SSL的唯一组合),但是某些主机比其他主机更频繁地通信。如果“大量”主机的数量> 100,则很可能必须为之前已连接到的“频繁”主机打开新连接,因为池必须关闭它们以为当前不在池中的主机创建连接。那会影响性能。但是,如果您为“频繁”主机创建了单独的池,则可以使这些主机连接保持更长时间。它们不必与所有那些不频繁的主机连接一起从“一般使用”的池中竞争免费连接。在aiohttp中,您可以通过使用不同的会话来创建不同的池,随后您需要定义逻辑来选择给定请求使用的会话。相比之下,同步HTTP API“requests”库处理方式略有不同,您可以针对每个URL前缀注册单独的传输适配器

其次,你的回答建议使用单个会话并操纵(1)connectorlimitlimit_per_host参数以及(2)会话实例本身的参数,而不是为每个批次创建单独的会话。(“但如果您为‘频繁’主机创建了单独的池,则可以更长时间地保持这些主机连接处于打开状态。”——似乎更简单的方法是仅增加1个会话的连接限制。)我理解得对吗? - Brad Solomon
1
@BradSolomon:不,操作“limit”和“limit_per_host”在所述情况下是无济于事的。假设DMOZ项目仍然存在,并且您正在尝试对其进行抓取。您将运行一系列任务以连接到DMOZ,检索其他站点的URL,然后抓取这些其他站点。那是很多URL,您不想失去与DMOZ的连接。limit_per_host将限制DMOZ连接,连接到大量其他域名的连接永远不会达到limit_per_host。一堆慢速外部URL将耗尽“limit”池。 - Martijn Pieters
1
@PirateApp:使用一个会话对象,它将处理连接重用,如果您的某些URL最终在同一台服务器上,否则当您的URL转到完全不同的服务器时,它将为您提供新的连接。默认情况下处理100个唯一连接,使用50个URL,您永远不会达到该限制。 - Martijn Pieters
谢谢@MartijnPieters,当你超过100时会发生什么?程序会崩溃吗? - PirateApp
1
@PirateApp:请仔细阅读我的回答。不,它不会崩溃,但是缓存的打开连接将被关闭以腾出空间给新的连接。 - Martijn Pieters
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接