Python 何时应将单个会话实例用于请求?

Python 何时应将单个会话实例用于请求?,python,python-requests,aiohttp,Python,Python Requests,Aiohttp,从aiohttp文档: [Anaiohttp.ClientSession]封装连接池(连接器实例),默认情况下支持keepalives除非您在应用程序的生命周期内连接到大量未知数量的不同服务器,否则建议您在应用程序的生命周期内使用单个会话,以受益于连接池。 我几乎总是使用一个ClientSession实例(启用cookies&自定义连接器/适配器*)来处理任意大小或容器的URL,不管这些URL有多异构或有多少个。我想知道这种方法是否有缺点 我希望对“大量未知数量的不同服务器”在实践中所构成的内容

aiohttp
文档:

[An
aiohttp.ClientSession
]封装连接池(连接器实例),默认情况下支持keepalives除非您在应用程序的生命周期内连接到大量未知数量的不同服务器,否则建议您在应用程序的生命周期内使用单个会话,以受益于连接池。

我几乎总是使用一个
ClientSession
实例(启用cookies&自定义连接器/适配器*)来处理任意大小或容器的URL,不管这些URL有多异构或有多少个。我想知道这种方法是否有缺点

我希望对“大量未知数量的不同服务器”在实践中所构成的内容有一个更精细的上下文定义。对于下面介绍的案例,最佳实践是什么?是否应该为每个netloc指定一个
ClientSession
,而不是为整个集合指定一个实例?**是否仅由响应时间决定是否使用单个客户端会话

通常情况下,我有“批”端点;每个批次的净LOC是同质的,但批次之间的净LOC是不同的。比如说,

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\u per\u host=10)
来限制对任何单个主机的打开连接


**具体而言,
{'www.thesaurus.com','aiohttp.readthedocs.io','httpbin.org'}

您可能希望在以下情况下使用专用会话及其自己的连接器:

  • 您需要为一组连接自定义连接器参数(例如,更改每台主机的限制,或更改SSL配置,或设置不同的超时)
  • 您将运行默认的100个连接限制,此时到现有主机的缓存连接被回收的可能性与仍然打开的可能性相同
  • 后一种情况是文档所暗示的。假设您要连接的唯一主机数量较多(其中唯一主机是主机名、端口号以及是否使用SSL的唯一组合),但其中一些主机的联系频率高于其他主机。如果该“大数”大于100,则您可能必须继续为之前已连接的“频繁”主机打开新连接,因为池必须关闭这些连接才能为当前不在池中的主机创建连接。那会影响表演

    但是,如果您为“频繁”主机创建了一个单独的池,那么您可以让这些主机连接保持更长的开放时间。他们不必与所有那些不频繁的主机连接竞争“通用”池中的免费连接

    在aiohttp中,通过使用单独的会话创建单独的池,然后必须定义逻辑来选择用于给定请求的会话


    相比之下,
    请求
    库(一个同步HTTP API)处理这个问题的方式稍有不同,如果可以的话。

    谢谢。为了证实我的理解,(默认值100)的
    limit
    参数指的是到一组主机的最大打开连接数,而不是单个/完整URI?其次,您的答案建议使用单个会话并操作(1)
    limit
    limit\u per\u host
    参数到
    connector
    和(2)会话实例本身的参数,而不是为每个批创建单独的会话。(“但是如果你为“频繁”的主机创建了一个单独的池,那么你可以让这些主机连接保持更长的开放时间。”——似乎更简单的方法是只增加一个会话的连接限制。)我的解释正确吗?@BradSolomon:是的,连接池限制是针对连接数量的,这是每台主机。请求
    example.com/foo/bar
    然后再请求
    example.com/spam/ham
    可以重用到
    example.com
    的打开连接(前提是另一个异步IO任务尚未使用)。@BradSolomon:不,在所述场景中操纵
    limit
    limit\u per\u主机
    不会有帮助。假设那只狗还活着,而你正试图把它刮下来。您将运行一系列任务来连接到DMOZ,检索其他站点的URL,然后刮取这些其他站点。这是大量的URL,您不会希望失去与DMOZ的连接。每个主机的限制将限制DMOZ连接,到大量其他域的连接将永远不会达到每个主机的限制。然而,一堆缓慢的外部URL将耗尽
    限制