每秒发出的异步aiohttp并行请求

2024-09-30 10:40:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我查看了这篇帖子(但我无法回复):aiohttp: rate limiting parallel requests

首先,我要感谢@Sraw他在上述帖子中的评论

但是,我怀疑我目前的解决方案是否做得很好:

for convertedJson in allJsons:
   .....
   .....
   tasks.append(asyncio.ensure_future(fetch(env,typeRequest,convertedJson,headers,retries,execution,session)))
   await asyncio.sleep(1/800)

results = await asyncio.gather(*tasks,return_exceptions=True)
await session.close()

在我的fetch函数中,我基本上是这样做的:

async def fetch(env,typeRequest,request,headers,retries,execution,session): 
   .....
   .....
   async with session.post(url=VALIDATION_API_ENDPOINT,json=request["body_request"],headers=headers,timeout=None,allow_redirects=False) as response:
      ......
      ......
      jsonF=await response.json()
      return jsonF

问题是我想每秒发出800个请求。我做得对吗?。我想很明显,我不知道需要多长时间才能收到答复。我想知道我是否已经用这种逻辑实现了800请求/秒,因为服务器人员告诉我,我实际上实现了400请求/秒左右(对我来说没有意义)

谢谢大家! 比尔


Tags: envasyncioasyncreturnrequestsessionfetchawait
1条回答
网友
1楼 · 发布于 2024-09-30 10:40:15

Asyncio不执行最大执行时间,只执行最小执行时间。此代码:

for convertedJson in allJsons:
    ...
    tasks.append(asyncio.ensure_future(fetch(env,typeRequest,convertedJson,headers,retries,execution,session)))
    await asyncio.sleep(1/800)

是否有下列情况:

  • 迭代convertedJson
  • 附加一个对象
  • 睡眠时间至少为1/800

当您仅延迟1.25毫秒秒时,执行所有其他步骤所需的时间就开始变得重要。您的asyncio事件循环还有其他需要服务的东西(比如实际执行请求),它开始显示:您并没有在一秒钟内完成800个请求。您甚至可能无法通过将它们添加到队列,因为该循环中的步骤需要一段时间。你肯定没有完成所有的任务(如你所见)

因此,总而言之:

  • 你的其他事件不是原子性的,所以即使你只睡了1.25毫秒,如果时间太长,你也会开始遇到问题(因为你不会在1秒内完成800次循环迭代)
  • asyncio的1.25ms是最好的,但允许更长。它可能在这里

怎么办?800个请求/秒显然与您当前的设置相当困难。您可能希望从请求代码中拆分生成这些请求,并在一个专用于执行抓取的线程中运行asyncio事件循环。您可能希望尝试信号量解决方案,它可能(猜测)具有较低的开销。您可能希望让更多的代码等待(这样eventloop可以更好地安排您的任务)。最后,您可能希望在几个线程之间批处理请求,但这是最后的建议,因为协作多任务处理的关键是避免多个线程

作为第一个赌注,甚至在你开始分析你的代码之前,看看你花了这么长的时间,去掉睡眠线,看看你每秒发出多少请求。这将使您了解达到所需吞吐量需要做多少工作

相关问题 更多 >

    热门问题