[英]Why aiohttp works slower than requests wrapped by run_in_executor?
全部!
我需要向 web 服务发出大约 10,000 个请求,我希望 JSON 会做出响应。 由于请求彼此独立,我想并行运行它们。 我认为aiohttp
可以帮助我。 我写了以下代码:
import asyncio
import aiohttp
async def execute_module(session: aiohttp.ClientSession, module_id: str,
post_body: dict) -> dict:
headers = {
'Content-Type': r'application/json',
'Authorization': fr'Bearer {TOKEN}',
}
async with session.post(
fr'{URL}/{module_id}/steps/execute',
headers=headers,
json=post_body,
) as response:
return await response.json()
async def execute_all(campaign_ids, post_body):
async with aiohttp.ClientSession() as session:
return await asyncio.gather(*[
execute_module(session, campaign_id, post_body)
for campaign_id in campaign_ids
])
campaign_ids = ['101', '102', '103'] * 400
post_body = {'inputs': [{"name": "one", "value": 1}]}
print(asyncio.run(execute_all(campaign_ids, post_body)))
PS我提出了 1,200 个测试请求。
另一种解决方法 - 在run_in_executor
function 中包装requests.post
。 我知道在异步 function 中使用阻塞代码是错误的,但它工作得更快(~ 7 秒 vs. ~ 10 秒 aiohttp)
import requests
import asyncio
def execute_module(module_id, post_body):
headers = {
'Content-Type': r'application/json',
'Authorization': fr'Bearer {TOKEN}',
}
return requests.post(
fr'{URL}/{module_id}/steps/execute',
headers=headers,
json=post_body,
).json()
async def execute_all(campaign_ids, post_body):
loop = asyncio.get_running_loop()
return await asyncio.gather(*[
loop.run_in_executor(None, execute_module, campaign_id, post_body)
for campaign_id in campaign_ids
])
campaign_ids = ['101', '102', '103'] * 400
post_body = {'inputs': [{"name": "one", "value": 1}]}
print(asyncio.run(execute_all(campaign_ids, post_body)))
我究竟做错了什么?
loop.run_in_executor(None, ...)
在线程池(多线程)中运行同步代码。 事件循环在一个线程中运行代码。
我的猜测是等待 IO 应该不会有太大的不同,但处理响应(即 json 解码)会。
你试过 uvloop - https://github.com/MagicStack/uvloop吗? 这应该会提高 aiohttp 请求的速度
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.