最大化并行请求数(aiohttp) - python

tl; dr:如何最大限度地增加可以并行发送的http请求的数量?

我正在使用aiohttp库从多个URL获取数据。我正在测试其性能,并且发现该过程中的某个地方存在瓶颈,一次运行更多的URL毫无帮助。

我正在使用此代码:

import asyncio
import aiohttp

async def fetch(url, session):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0'}
    try:
        async with session.get(
            url, headers=headers, 
            ssl = False, 
            timeout = aiohttp.ClientTimeout(
                total=None, 
                sock_connect = 10, 
                sock_read = 10
            )
        ) as response:
            content = await response.read()
            return (url, 'OK', content)
    except Exception as e:
        print(e)
        return (url, 'ERROR', str(e))

async def run(url_list):
    tasks = []
    async with aiohttp.ClientSession() as session:
        for url in url_list:
            task = asyncio.ensure_future(fetch(url, session))
            tasks.append(task)
        responses = asyncio.gather(*tasks)
        await responses
    return responses

loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
task = asyncio.ensure_future(run(url_list))
loop.run_until_complete(task)
result = task.result().result()

我用不同长度的url_list运行此代码(针对https://httpbin.org/delay/2进行测试),我发现一次添加更多的url最多只能运行约100个url,然后总时间开始与url的数量成正比(或其他形式)字,每个网址的时间不会减少)。这表明尝试立即处理这些操作时某些操作失败。此外,“一批”中有更多url,我偶尔会收到连接超时错误。

最大化并行请求数(aiohttp) - python

为什么会这样呢?到底什么限制了速度?
如何检查可以在给定计算机上发送的并行请求的最大数量? (我的意思是确切的数字-并非如上所述的“反复试验”的近似值)
如何增加一次处理的请求数量?

我在Windows上运行。

编辑以回应评论:

这是相同的数据,其限制设置为None。最后只有一点改进,并且一次发送了400个URL时有很多连接超时错误。我最终在实际数据上使用了limit = 200

最大化并行请求数(aiohttp) - python

参考方案

默认情况下,aiohttp将同时连接数限制为100。通过将limit使用的默认TCPConnector设置为ClientSession object来实现。您可以通过创建自定义连接器并将其传递到会话来绕过它:

connector = aiohttp.TCPConnector(limit=None)
async with aiohttp.ClientSession(connector=connector) as session:
    # ...

但是请注意,您可能不想将此数字设置得太高:您的网络容量,CPU,RAM和目标服务器有其自身的限制,并尝试进行大量连接会导致故障增加。

最佳数量可能只能通过在混凝土机器上进行实验才能找到。

无关:

如果没有reason,则不必创建任务。大多数异步api接受常规协程。例如,您的最后几行代码可以通过以下方式更改:

loop = asyncio.get_event_loop()
loop.run_until_complete(run(url_list))

如果您使用的是Python 3.7,甚至只是asyncio.run(run(url_list))(doc)

Python-尝试使用意外的mimetype解码JSON: - python

我最近从请求切换到了aiohttp,因为我无法在asyncio循环中使用它。交换进行得很顺利,除一件事外,其他一切都进行得很好。我的控制台充满了Attempt to decode JSON with unexpected mimetype: 和Attempt to decode JSON with unexpected mimetype: txt/html;…

python asyncio run_forever或True - python

我应该在代码中替换while True(不使用asyncio)还是应该使用asyncio事件循环来实现相同的结果。目前,我正在处理某种与“ zeromq”连接的“工作者”,接收一些数据,然后对外部工具(服务器)执行一些请求(http)。一切都以普通的阻塞IO编写。使用asyncio事件循环摆脱while True: ...是否有意义?将来可能会用asynci…

Python GPU资源利用 - python

我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…

Aiohttp认证中间件 - python

我想将中间件附加到特定的处理程序,并且如果未授权客户端,则想返回错误响应。但是,使用以下代码:async def middleware_factory(app, handler): async def auth_handler(request): if request.headers.get('Authorization') == �…

Python:图像处理可产生皱纹纸效果 - python

也许很难描述我的问题。我正在寻找Python中的算法,以在带有某些文本的白色图像上创建皱纹纸效果。我的第一个尝试是在带有文字的图像上添加一些真实的皱纹纸图像(具有透明度)。看起来不错,但副作用是文本没有真正起皱。所以我正在寻找更好的解决方案,有什么想法吗?谢谢 参考方案 除了使用透明性之外,假设您有两张相同尺寸的图像,一张在皱纹纸上明亮,一张在白色背景上有深…