Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 了解aiohttp.tcp连接器池&;连接限制_Python_Python 3.x_Python Asyncio_Aiohttp - Fatal编程技术网

Python 了解aiohttp.tcp连接器池&;连接限制

Python 了解aiohttp.tcp连接器池&;连接限制,python,python-3.x,python-asyncio,aiohttp,Python,Python 3.x,Python Asyncio,Aiohttp,我正在试验limit和limit\u per\u host参数到aiohttp.connector.TCPConnector 在下面的脚本中,我将connector=aiohttp.connector.TCPConnector(limit=25,limit\u per\u host=5)传递到aiohttp.ClientSession,然后向docs.aiohttp.org打开2个请求,向github.com打开3个请求 session.request的结果是aiohttp.ClientResp

我正在试验
limit
limit\u per\u host
参数到
aiohttp.connector.TCPConnector

在下面的脚本中,我将
connector=aiohttp.connector.TCPConnector(limit=25,limit\u per\u host=5)
传递到
aiohttp.ClientSession
,然后向docs.aiohttp.org打开2个请求,向github.com打开3个请求

session.request
的结果是
aiohttp.ClientResponse
的一个实例,在本例中,我有意不通过
.close()
\uuuuuuuuuuuuuu
对其调用
.close()
。我假设这将使连接池保持打开状态,并将到该连接(主机、ssl、端口)的可用连接减少三倍-1

下表显示了每个请求后可用的连接数()为什么即使在完成了对docs.aiohttp.org的第二次请求之后,数字仍然挂在4上?这两个连接可能仍然处于打开状态,尚未访问或关闭
\u内容。可用连接不是应该减少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

输出被粘贴到。我把它放在那里而不是这里,因为行很长,不能很好地包装。

为了解决您的主要问题“为什么在完成对docs.aiohttp.org的第二次请求后,数字仍然挂在4?”, 调用
aiohttp.connector.BaseConnector.\u release()
时,连接计数将减少,如果要在
session.request()上使用
async with
,则将调用此函数 或者显式调用
.close()
,或者在使用
.read()
读取响应内容之后调用。或者与服务器发送EOF时docs.aiohttp.org请求的情况相同(当服务器不等待您流式传输响应内容,而是响应第一个请求发送所有内容时,会发生这种情况)。这就是这里正在发生的事情。当您在
aiohttp.connector.BaseConnector.\u release()
中放置断点并检查堆栈时,您将看到调用了
aiohttp.http\u parser.DeflateBuffer.feed\u eof()
。而
aiohttp.streams.StreamReade.\u eof\u回调
包含
aiohttp.client\u requrep.ClientResponse.\u response\u eof()
调用
self.\u connection.release()


至于你的第二个问题“为什么每个主机的
只包含一个键”,这很奇怪。但是我在医生里什么也看不到。这是一个私人属性,所以我们不应该弄乱它。它可能只是一个名字不好的私有属性。

就在我脑海中;您有aiohttp连接池,但也有连接重用和保持有效性。后者会影响你脚本的计数吗?@ElToro1966我也想看一下,但看起来默认的保持活动时间是15.0秒。看来这不会在这里起作用吧?
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())