aiohttp:速率限制并行请求

API通常具有用户必须遵循的速率限制。举个例子,让我们50个请求/秒。连续的请求采取0.5-1秒,因此是来接近极限速度太慢。但是,使用aiohttp的并行请求超出了速率限制。

轮询API尽可能快地允许,需要限速并行调用。

例如,我发现到目前为止装饰session.get,大约像这样:

session.get = rate_limited(max_calls_per_second)(session.get)

这非常适用于连续通话。试图并行调用来实现这个按预期不起作用。

下面是一些代码示例:

async with aiohttp.ClientSession() as session:

session.get = rate_limited(max_calls_per_second)(session.get)

tasks = (asyncio.ensure_future(download_coroutine(

timeout, session, url)) for url in urls)

process_responses_function(await asyncio.gather(*tasks))

这里的问题是,它会率限制 的任务。与执行gather也会出现或多或少的在同一时间。两个世界最糟的;-)。

是的,我发现了一个类似的问题在这里aiohttp:每秒请求设定的最大数目,但既不答复答复限制请求的速率的实际问题。此外,从昆汀·普拉代博客文章仅适用于限速排队。

要包起来:一个人怎么可以限制 每秒请求数 并行aiohttp请求?

回答:

如果我理解你很好,你想限制并发请求数?

有一个内部的对象asyncio命名Semaphore,它就像一个异步RLock

semaphore = asyncio.Semaphore(50)

#...

async def limit_wrap(url):

async with semaphore:

# do what you want

#...

results = asyncio.gather([limit_wrap(url) for url in urls])

更新

假设我做50个并发请求,他们也都在2秒内完成。因此,它不接触限制(只有每秒25个请求)。

这意味着我应该做100个并发请求,他们也都在2秒内太(每秒50个请求)完成。但在此之前,你实际上使这些要求,你怎么能确定他们将如何悠长?

或者,如果你不介意 但 。您可以:

async def loop_wrap(urls):

for url in urls:

asyncio.ensure_future(download(url))

await asyncio.sleep(1/50)

asyncio.ensure_future(loop_wrap(urls))

loop.run_forever()

上面的代码将创建一个Future实例每隔1/50一秒。

以上是 aiohttp:速率限制并行请求 的全部内容, 来源链接: utcz.com/qa/422525.html

回到顶部