- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在试验 limit
和 limit_per_host
参数到 aiohttp.connector.TCPConnector
。
在下面的脚本中,我将 connector = aiohttp.connector.TCPConnector(limit=25, limit_per_host=5)
传递给 aiohttp.ClientSession
,然后打开 2 个请求到docs.aiohttp.org 和 3 到 github.com。
session.request
的结果是 aiohttp.ClientResponse
的实例,在这个例子中我有意不调用 .close()
在上面,通过 .close()
或 __aexit__
。我假设这将使连接池保持打开状态,并将到该(主机、ssl、端口)的可用连接减少三倍 -1。
下表表示每次请求后的 ._available_connections()
。 为什么即使在完成对 docs.aiohttp.org 的第二次请求后数字仍停留在 4?这两个连接可能仍处于打开状态并且尚未访问 ._content
或被关闭。可用连接数不应该减少 1 吗?
After Request Num. To _available_connections
1 docs.aiohttp.org 4
2 docs.aiohttp.org 4 <--- Why?
3 github.com 4
4 github.com 3
5 github.com 2
此外,为什么 ._acquired_per_host
只包含 1 个 key ?我想我可能正在理解 TCPConnector
的方法;如何解释上述行为?
完整脚本:
import aiohttp
async def main():
connector = aiohttp.connector.TCPConnector(limit=25, limit_per_host=5)
print("Connector arguments:")
print("_limit:", connector._limit)
print("_limit_per_host:", connector._limit_per_host)
print("-" * 70, end="\n\n")
async with aiohttp.client.ClientSession(
connector=connector,
headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36"},
raise_for_status=True
) as session:
# Make 2 connections to docs.aiohttp.org and
# 3 connections to github.com
#
# Note that these instances intentionally do not use
# .close(), either explicitly or via __aexit__
# in an async with block
r1 = await session.request(
"GET",
"https://docs.aiohttp.org/en/stable/client_reference.html#connectors"
)
print_connector_attrs("r1", session)
r2 = await session.request(
"GET",
"https://docs.aiohttp.org/en/stable/index.html"
)
print_connector_attrs("r2", session)
r3 = await session.request(
"GET",
"https://github.com/aio-libs/aiohttp/blob/master/aiohttp/client.py"
)
print_connector_attrs("r3", session)
r4 = await session.request(
"GET",
"https://github.com/python/cpython/blob/3.7/Lib/typing.py"
)
print_connector_attrs("r4", session)
r5 = await session.request(
"GET",
"https://github.com/aio-libs/aiohttp"
)
print_connector_attrs("r5", session)
def print_connector_attrs(name: str, session: aiohttp.client.ClientSession):
print("Connection attributes for", name, end="\n\n")
conn = session._connector
print("_conns:", conn._conns, end="\n\n")
print("_acquired:", conn._acquired, end="\n\n")
print("_acquired_per_host:", conn._acquired_per_host, end="\n\n")
print("_available_connections:")
for k in conn._acquired_per_host:
print("\t", k, conn._available_connections(k))
print("-" * 70, end="\n\n")
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
输出粘贴在 https://pastebin.com/rvfzMTe3 .我把它放在那里而不是放在这里,因为这些行很长而且不太适合换行。
最佳答案
要解决您的主要问题“为什么即使在完成对 docs.aiohttp.org 的第二次请求后数字仍停留在 4?”,当 aiohttp.connector.BaseConnector._release()
被调用时,连接计数将减少,如果您要在 session 上使用
或显式调用 async with
,则会调用此方法.request().close()
或在您使用 .read()
读取响应内容后。或者在 docs.aiohttp.org 请求的情况下,当服务器发送 EOF 时(当服务器不等待您流式传输响应内容而是将其全部发送以响应第一个请求时,就会发生这种情况)。这就是这里正在发生的事情。当您在 aiohttp.connector.BaseConnector._release()
中放置断点并检查堆栈时,您可以亲眼看到 aiohttp.http_parser.DeflateBuffer.feed_eof()
被调用。 aiohttp.streams.StreamReade._eof_callbacks
包含正在调用 self._connection.release()
的 aiohttp.client_reqrep.ClientResponse._response_eof()
至于你的第二个问题“为什么 ._acquired_per_host
只包含 1 个 key ”,这很奇怪。但是我在文档中什么也看不到。这是一个私有(private)属性,所以我们不应该弄乱它。它可能只是命名错误的私有(private)属性。
关于python - 了解 aiohttp.TCPConnector 池和连接限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53961359/
我正在试验 limit 和 limit_per_host 参数到 aiohttp.connector.TCPConnector。 在下面的脚本中,我将 connector = aiohttp.conn
我一直在尝试在 aiohttp 中使用连接池,但运气不佳。用例是代码重复向一些服务器发出请求,我不想在每个请求上重新创建连接。下面是一些重现该问题的代码(错误是超时上下文管理器应该在任务内使用): i
我想我想学习新的 python async await 语法,更具体地说是 asyncio 模块,方法是制作一个允许您一次下载多个资源的简单脚本。 但现在我卡住了。 在研究过程中,我遇到了两个限制并发
我是一名优秀的程序员,十分优秀!