Aiohttp服务器最大连接数

时间:2019-05-27 06:38:40

标签: python-asyncio aiohttp

我无法理解aiohttp(通常是asyncio)服务器实现没有提供限制最大并发连接数限制(接受的套接字数或正在运行的请求处理程序数)的原因。 (https://github.com/aio-libs/aiohttp/issues/675)。没有此限制,很容易耗尽内存和/或文件描述符。

同时,默认情况下,aiohttp客户端将并发请求数限制为100(https://docs.aiohttp.org/en/stable/client_advanced.html#limiting-connection-pool-size),aiojobs限制了正在运行的任务数和未决任务列表的大小,nginx具有worker_connections限制,任何同步框架都受到限制根据设计的工作线程数。

虽然aiohttp可以处理许多并发请求,但此数量仍然有限。关于aiojobs的文档说:“ Scheduler暗含了对并发作业数量的限制(默认为100个)。...它通过同时运行十亿个作业来防止程序溢出。”而且,我们仍然可以愉快地产生aiohttp处理程序“十亿”(好,直到我们用尽资源)。

问题是,为什么要按原样实施?我是否缺少一些重要的细节?我认为我们可以使用Semafor暂停请求处理程序,但是与nginx相比,套接字仍然被aiohttp接受并且生成了协程。同样,在nginx后面进行部署时,worker_connections的数量和aiohttp所需的限制肯定会有所不同。(因为nginx也可以提供静态文件)

2 个答案:

答案 0 :(得分:1)

基于开发者对linked issue的评论,选择该选项的原因如下:

  • 如果应用程序检测到连接数大于其合理处理的数量,则可以返回4xx或5xx响应。 (这与Semaphore惯用语不同,后者会有效地排队连接。)

  • 限制服务器连接数比仅指定一个数要复杂得多,因为限制可能完全取决于协程的作用,即,它至少应基于路径。安德鲁·斯维特洛夫(Andrew Svetlov)链接到NGINX documentation,以了解支持连接的限制。

  • 无论如何,建议将aiohttp放在专门的前端服务器(如NGINX)后面。

仅由已知读取此标签的开发人员才能提供比这更多的详细信息。

这时,似乎推荐的解决方案是使用反向代理进行限制,或使用基于应用程序的限制(例如此装饰器)(未测试):

REQUEST_LIMIT = 100

def throttle_handle(real_handle):
    _nrequests = 0
    async def handle(request):
        nonlocal _nrequests
        if _nrequests >= REQUEST_LIMIT:
            return aiohttp.web.Response(
                status=429, text="Too many connections")
        _nrequests += 1
        try:
            return await real_handle(request)
        finally:
            _nrequests -= 1
    return handle

@throttle_handle
async def handle(request):
    ... your handler here ...

答案 1 :(得分:1)

要限制并发连接,您可以使用 aiohttp.TCPConnectoraiohttp.ProxyConnector(如果您使用代理)。只需在会话中创建它,而不是使用默认值。

aiohttp.ClientSession(
    connector=aiohttp.TCPConnector(limit=1)
)
aiohttp.ClientSession(
    connector=aiohttp.ProxyConnector.from_url(proxy_url, limit=1)
)