簡體   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