1 回答
TA贡献1859条经验 获得超6个赞
这可以安全地在生产环境中运行,但 asyncio 无法与 Gunicorn 异步工作线程(例如 gevent 或 eventlet)有效配合。这是因为
result_a, result_b = asyncio.run(contact_apis())
将会阻止 gevent/eventlet 事件循环直到其完成,而使用 gevent/eventlet 生成等效项则不会。Flask 服务器不应该在生产中使用。Gunicorn 线程工作线程(或多个 Gunicorn 进程)会很好,因为 asyncio 会阻塞线程/进程。全局变量可以正常工作,因为它们与线程(线程工作线程)或绿色线程(gevent/eventlet)相关联,而不是与 asyncio 任务相关联。
我想说Quart是一种改进。Quart 是使用 asyncio 重新实现的 Flask API。对于 Quart,上面的代码片段是:
import asyncio
import random
import time
from quart import Quart
app = Quart(__name__)
async def contact_api_a():
print(f'{time.perf_counter()}: Start request 1')
# This sleep simulates querying and having to wait for an external API
await asyncio.sleep(2)
# Here is our simulated API reply
result = random.random()
print(f'{time.perf_counter()}: Finish request 1')
return result
async def contact_api_b():
print(f'{time.perf_counter()}: Start request 2')
await asyncio.sleep(1)
result = random.random()
print(f'{time.perf_counter()}: Finish request 2')
return result
async def contact_apis():
# Create the two tasks
task_a = asyncio.create_task(contact_api_a())
task_b = asyncio.create_task(contact_api_b())
# Wait for both API requests to finish
result_a, result_b = await asyncio.gather(task_a, task_b)
print(f'{time.perf_counter()}: Finish both requests')
return result_a, result_b
@app.route('/')
async def hello_world():
start_time = time.perf_counter()
# All async processes are organized in a separate function
result_a, result_b = await contact_apis()
# We implement some final business logic before finishing the request
final_result = result_a + result_b
processing_time = time.perf_counter() - start_time
return f'Result: {final_result:.2f}; Processing time: {processing_time:.2f}'
我还建议使用基于 asyncio 的请求库,例如httpx
添加回答
举报