什么时候应该将单个会话实例用于请求?
When should a single session instance be used for requests?
来自 aiohttp
文档:
[An aiohttp.ClientSession
] encapsulates a connection pool (connector instance) and supports keepalives by default. Unless you are connecting to a large, unknown number of different servers over the lifetime of your application, it is suggested you use a single session for the lifetime of your application to benefit from connection pooling.
我几乎总是使用为任何大小或容器的 URL 保留单个 ClientSession
实例(启用 cookie 和自定义 connector/adapter*)的做法,无论这些 URL 多么异构是或有多少人。我想知道这种方法是否有缺点。
我希望对 "large, unknown number of different servers" 在实践中的构成有一个更细化的上下文定义。对于下面介绍的案例,最佳做法是什么? ClientSession
是否应该专用于每个 netloc,而不是整个集合的单个实例?** 是否仅由响应时间决定是否使用单个客户端会话?
通常情况下我有 "batches" 个端点;每个批次的 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'
}
打个数字,实际上每批的长度大概是 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)
。
当
时,您希望使用带有自己的连接器的专用会话
- 您想为一组连接自定义连接器参数(例如,更改每个主机的限制,或更改 SSL 配置,或设置不同的超时)。
- 您将 运行 通过默认的 100 个连接限制,此时与现有主机的缓存连接被回收的可能性与仍然打开的可能性一样。
后一种情况是文档所暗示的。假设您有大量的唯一主机要连接(其中唯一主机是主机名、端口号以及是否使用 SSL 的唯一组合),但是 some 这些主机比其他人更频繁地联系。如果 'large number' > 100,那么您可能必须继续为之前已经连接的 'frequent' 主机打开新连接,因为池必须关闭它们才能为主机创建连接目前不在池中。这会影响性能。
但是,如果您为 'frequent' 主机创建了一个 单独的 池,那么您可以使这些主机连接打开的时间更长。他们不必与所有那些不频繁的主机连接竞争来自 'general use' 池的免费连接。
在 aiohttp 中,您通过使用单独的会话创建单独的池,然后您必须定义逻辑来选择用于给定请求的会话。
相比之下,requests
库(同步 HTTP API)处理这个问题的方式略有不同,您可以 register separate transport adapters per url prefix.
来自 aiohttp
文档:
[An
aiohttp.ClientSession
] encapsulates a connection pool (connector instance) and supports keepalives by default. Unless you are connecting to a large, unknown number of different servers over the lifetime of your application, it is suggested you use a single session for the lifetime of your application to benefit from connection pooling.
我几乎总是使用为任何大小或容器的 URL 保留单个 ClientSession
实例(启用 cookie 和自定义 connector/adapter*)的做法,无论这些 URL 多么异构是或有多少人。我想知道这种方法是否有缺点。
我希望对 "large, unknown number of different servers" 在实践中的构成有一个更细化的上下文定义。对于下面介绍的案例,最佳做法是什么? ClientSession
是否应该专用于每个 netloc,而不是整个集合的单个实例?** 是否仅由响应时间决定是否使用单个客户端会话?
通常情况下我有 "batches" 个端点;每个批次的 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'
}
打个数字,实际上每批的长度大概是 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)
。
当
时,您希望使用带有自己的连接器的专用会话- 您想为一组连接自定义连接器参数(例如,更改每个主机的限制,或更改 SSL 配置,或设置不同的超时)。
- 您将 运行 通过默认的 100 个连接限制,此时与现有主机的缓存连接被回收的可能性与仍然打开的可能性一样。
后一种情况是文档所暗示的。假设您有大量的唯一主机要连接(其中唯一主机是主机名、端口号以及是否使用 SSL 的唯一组合),但是 some 这些主机比其他人更频繁地联系。如果 'large number' > 100,那么您可能必须继续为之前已经连接的 'frequent' 主机打开新连接,因为池必须关闭它们才能为主机创建连接目前不在池中。这会影响性能。
但是,如果您为 'frequent' 主机创建了一个 单独的 池,那么您可以使这些主机连接打开的时间更长。他们不必与所有那些不频繁的主机连接竞争来自 'general use' 池的免费连接。
在 aiohttp 中,您通过使用单独的会话创建单独的池,然后您必须定义逻辑来选择用于给定请求的会话。
相比之下,requests
库(同步 HTTP API)处理这个问题的方式略有不同,您可以 register separate transport adapters per url prefix.