[英]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.