Python异步REST API,其响应依赖于CPU密集型计算。如何有效地处理? [重复]

问题描述 投票:2回答:1

我使用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秒后从快速终点接收响应。

我花了最后几个小时绕圈子,阅读asynciomultiprocessing,但无法找到任何可以解决我问题的东西。可能我需要花更长的时间来研究这个领域以获得更好的理解,但希望我能够朝着正确的方向努力实现预期的结果。

python multiprocessing python-3.6 aiohttp
1个回答
3
投票

在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}
© www.soinside.com 2019 - 2024. All rights reserved.