Python 异步 REST API 响应依赖于 CPU 密集计算。如何高效处理?
Python asynchronous REST API with responses which rely on CPU intensive calculations. How to handle efficiently?
我已经使用 aiohttp
编写了一个基本的 REST API,下面包含一个简化版本来说明我要解决的问题。
API 有两个端点 - 每个端点都调用一个执行某些计算的函数。两者之间的区别在于,其中一个端点的计算时间为 10 秒,而另一个端点的计算时间仅为 1 秒。
我的代码如下(实际计算已替换为 time.sleep()
调用)。
import time
from aiohttp import web
def simple_calcs():
time.sleep(1) # Pretend this is the simple calculations
return {'test': 123}
def complex_calcs():
time.sleep(10) # Pretend this is the complex calculations
return {'test': 456}
routes = web.RouteTableDef()
@routes.get('/simple_calcs')
async def simple_calcs_handler(request):
results = simple_calcs()
return web.json_response(results)
@routes.get('/complex_calcs')
async def complex_calcs_handler(request):
results = complex_calcs()
return web.json_response(results)
app = web.Application()
app.add_routes(routes)
web.run_app(app)
我希望发生的事情:
如果我向较慢的端点发送请求,然后立即向较快的端点发送请求,我希望先从较快的端点接收响应,同时较慢的计算仍在进行中。
实际发生了什么:
较慢端点正在执行的计算正在阻塞。我在约 10 秒后收到来自慢端点的响应,并在约 11 秒后收到来自快速端点的响应。
过去几个小时我一直在兜圈子,阅读 asyncio
和 multiprocessing
,但找不到任何可以解决我的问题的东西。可能我需要花更长的时间研究这个领域以获得更好的理解,但希望我能朝着正确的方向前进,朝着预期的结果迈进。
在 asyncio 中应避免任何阻塞 IO 调用。
基本上time.sleep(10)
阻止整个 aiohttp 服务器 10 秒。
要解决它请使用loop.run_in_executor()调用:
async def complex_calcs():
loop = asyncio.get_event_loop()
loop.run_in_executor(None, time.sleep, 10) # Pretend this is the complex calculations
return {'test': 456}
我已经使用 aiohttp
编写了一个基本的 REST API,下面包含一个简化版本来说明我要解决的问题。
API 有两个端点 - 每个端点都调用一个执行某些计算的函数。两者之间的区别在于,其中一个端点的计算时间为 10 秒,而另一个端点的计算时间仅为 1 秒。
我的代码如下(实际计算已替换为 time.sleep()
调用)。
import time
from aiohttp import web
def simple_calcs():
time.sleep(1) # Pretend this is the simple calculations
return {'test': 123}
def complex_calcs():
time.sleep(10) # Pretend this is the complex calculations
return {'test': 456}
routes = web.RouteTableDef()
@routes.get('/simple_calcs')
async def simple_calcs_handler(request):
results = simple_calcs()
return web.json_response(results)
@routes.get('/complex_calcs')
async def complex_calcs_handler(request):
results = complex_calcs()
return web.json_response(results)
app = web.Application()
app.add_routes(routes)
web.run_app(app)
我希望发生的事情:
如果我向较慢的端点发送请求,然后立即向较快的端点发送请求,我希望先从较快的端点接收响应,同时较慢的计算仍在进行中。
实际发生了什么:
较慢端点正在执行的计算正在阻塞。我在约 10 秒后收到来自慢端点的响应,并在约 11 秒后收到来自快速端点的响应。
过去几个小时我一直在兜圈子,阅读 asyncio
和 multiprocessing
,但找不到任何可以解决我的问题的东西。可能我需要花更长的时间研究这个领域以获得更好的理解,但希望我能朝着正确的方向前进,朝着预期的结果迈进。
在 asyncio 中应避免任何阻塞 IO 调用。
基本上time.sleep(10)
阻止整个 aiohttp 服务器 10 秒。
要解决它请使用loop.run_in_executor()调用:
async def complex_calcs():
loop = asyncio.get_event_loop()
loop.run_in_executor(None, time.sleep, 10) # Pretend this is the complex calculations
return {'test': 456}