[英]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 的数量有关
然后我尝试使用 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.