当前位置: 首页 > 面试题库 >

aiohttp:速率限制并行请求

莘羽
2023-03-14
问题内容

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,它就像一个html" target="_blank">异步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一秒。



 类似资料:
  • 我正在写一个网络爬虫,运行并行抓取许多不同的域。我想限制每秒向每个域发出的请求数量,但我不关心打开的连接总数,也不关心跨所有域发出的每秒请求总数。我想最大限度地增加打开连接和每秒请求的总数,同时限制对单个域的每秒请求数。 我可以找到的所有现有示例(1)限制打开连接的数量,或(2)限制在fetch循环中每秒发出的请求总数。例子包括: aiohttp:速率限制并行请求 它们都不做我要求的事情,即限制每

  • 问题内容: 我正在用GRequests和lxml在Python 2.7.3中编写一个小脚本,这将允许我从各个网站收集一些可收集的卡价格并进行比较。问题是网站之一限制了请求的数量,如果我超过了它,则会发回HTTP错误429。 有没有一种方法可以限制GRequestes中的请求数量,以使我不超过我指定的每秒请求数量?另外-如果发生HTTP 429,如何让GRequestes在一段时间后重试? 附带说明

  • 我正在用Python 2.7.3编写一个小脚本,其中包含GRequests和lxml,它将允许我从各种网站收集一些可收集的卡价格并进行比较。问题是其中一个网站限制了请求的数量,如果我超过它,就会发回HTTP错误429。 有没有办法在grequests中增加限制请求数,这样我就不会超过我指定的每秒请求数?还有——如果HTTP 429出现,我如何让GRequestes在一段时间后重试? 另一方面,他们

  • 我正在使用ProjectReactor使用rest从web服务加载数据。这是与多个线程并行完成的。我开始达到web服务的速率限制,因此我希望每秒最多发送10个请求,以避免出现这些错误。用Reactor我该怎么做? 使用zipWith(Mono.delayMillis(100))?还是有更好的办法? 非常感谢。

  • 速率限制配置参考 filter.http.RateLimit filter.http.RateLimit proto { "domain": "...", "stage": "...", "request_type": "...", "timeout": "{...}" } domain (string, REQUIRED) 需要调用速率限制服务时的域。 stage (uint3

  • 速率限制配置参考。 filter.network.RateLimit filter.network.RateLimit proto { "stat_prefix": "...", "domain": "...", "descriptors": [], "timeout": "{...}" } stat_prefix (string, REQUIRED) 发布统计信息时使用的前缀。