繁体   English   中英

异步并发速率限制

[英]Asyncio concurrency rate limit

我是 python 新手,一直在尝试为与 asyncio 一起处理并发请求的程序设置速率限制,但是在尝试了我在 stackoverflow 和其他编程网站中找到的几乎所有内容之后,我真的不知道我是否遗漏了什么或者我我做错了,所以我希望社区可以帮助我。

对于 asyncio 程序,我的实现非常简单:

async def inside_api_call_1(data, session):
  r = await do_request()
  return r;

async def inside_api_call_2(data, session):
  r = await do_another_request()
  return r;

async def full_process(data, session):
  res1 = await inside_api_call_1(data, session)
  if (res1):
    res2 = await inside_api_call_1(data, session)

async def main_func():
  tasks = []
  async with aiohttp.ClientSession() as session:
    for data in some_json_file:
      tasks.append(full_process(data, session))
    await asyncio.gather(*tasks, return_exceptions=True)

loop = asyncio.get_event_loop()
loop.run_until_complete(main_block())

我想要做的是将这些 _api_call 函数的速率限制设置为 16 req/sec GLOBALLY(所有请求的总和(在这种情况下,我一个接一个地发出两个请求,因为第二个需要第一个结果才能继续) 不得超过 16 个请求/秒)

我的第一个想法是为这两个函数设置一个睡眠(1/16):

async def inside_api_call_1(data, session):
  r = await do_request()
  await asyncio.sleep(1/16) # <--- Wait 1/16 sec
  return r;

async def inside_api_call_2(data, session):
  r = await do_another_request()
  await asyncio.sleep(1/16) # <--- Wait 1/16 sec
  return r;

但它不起作用,因为我不断收到 429 Too Many Request 错误。

也尝试过信号量,但这个解决方案似乎更多地与同时活动连接的数量有关,而不是与 req / sec 的数量有关

aiohttp:设置每秒最大请求数

然后我尝试使用 python 包https://github.com/hallazzang/asyncio-throttle并将我的代码设置为:

async def main_func():
  tasks = []
  throttler = Throttler(rate_limit=16) <-- setting throttler to 16 req / sec
  async with throttler:
    async with aiohttp.ClientSession() as session:
      for data in some_json_file:
        tasks.append(full_process(data, session))
      await asyncio.gather(*tasks, return_exceptions=True)
  await asyncio.sleep(1/16) <-- This line as the documentation put in the example

loop = asyncio.get_event_loop()
loop.run_until_complete(main_block())

从这里我一直将 sleep 方法和 asyncio-throttle 进程的语句从 main_func 移动到 inside_api_call 方法:

async def inside_api_call_1(data, session):
  async with throttler:
    r = await do_request()
    await asyncio.sleep(1/16)
  return r;

async def inside_api_call_2(data, session):
  async with throttler:
    r = await do_another_request()
    await asyncio.sleep(1/16)
  return r;

没有成功。

我对 Python 中的异步也很陌生,因此可以得到任何帮助。

尝试https://pypi.org/project/limiter/

    async def main_func():
        tasks = []
        async with aiohttp.ClientSession() as session:
            for idx, data in enumerate(some_json_file):
                tasks.append(full_process(data, session))
                if idx % 16 == 0:
                    await asyncio.gather(*tasks, return_exceptions=True)
                    tasks = []
                    sleep(1)
            if tasks:
                await asyncio.gather(*tasks, return_exceptions=True)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM