You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask中异步函数阻塞其他请求问题排查

Flask启动时运行异步函数导致请求无法响应的问题分析与解决

问题根源

你直接在代码中调用asyncio.run(get_new_prices()),这个函数会启动异步事件循环并阻塞主线程,直到get_new_prices()协程完全执行完毕。这就导致Flask的app.run()根本没机会启动服务器,或者服务器启动前就被卡住,自然无法处理任何外部请求。

解决方案

方案一:用后台线程执行异步任务

把异步任务放到独立线程中运行,让主线程能正常启动Flask服务器:

from flask import Flask, request, jsonify
from flask_cors import CORS
import asyncio
import time
from scraper import scrap
from threading import Thread

DEBUG = True

app = Flask(__name__)
app.config.from_object(__name__)
CORS(app)

@app.route('/api/v1/request', methods=['POST'])
def process_order():
    # 你的业务代码
    return jsonify({"status": "success"})

async def get_new_prices():
    print('async started')
    start = time.time()
    res = await scrap()
    end = time.time() - start
    print(res, end)

def run_async_task():
    # 创建新的事件循环用于线程内执行异步任务
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(get_new_prices())

if __name__ == '__main__':
    # 启动后台守护线程,随主进程退出而终止
    Thread(target=run_async_task, daemon=True).start()
    app.run(debug=DEBUG)

方案二:用任务调度扩展管理后台任务

如果需要定时重复执行该异步任务,或者更规范地管理后台任务,可以使用Flask-APScheduler:

from flask import Flask, request, jsonify
from flask_cors import CORS
from flask_apscheduler import APScheduler
import asyncio
import time
from scraper import scrap

DEBUG = True

app = Flask(__name__)
app.config.from_object(__name__)
CORS(app)

# 配置调度器
app.config['SCHEDULER_API_ENABLED'] = True
scheduler = APScheduler()

@app.route('/api/v1/request', methods=['POST'])
def process_order():
    # 你的业务代码
    return jsonify({"status": "success"})

async def get_new_prices():
    print('async started')
    start = time.time()
    res = await scrap()
    end = time.time() - start
    print(res, end)

def run_async_task():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(get_new_prices())

if __name__ == '__main__':
    scheduler.init_app(app)
    # 添加启动时执行的一次性任务
    scheduler.add_job(id='startup_scrap_task', func=run_async_task, trigger='date')
    scheduler.start()
    app.run(debug=DEBUG)

方案三:改用原生支持异步的框架(FastAPI)

如果你的应用有大量异步操作需求,直接切换到FastAPI会更适配,它原生支持异步任务和启动事件:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import asyncio
import time
from scraper import scrap

app = FastAPI()

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.post("/api/v1/request")
async def process_order():
    # 你的业务代码
    return {"status": "success"}

async def get_new_prices():
    print('async started')
    start = time.time()
    res = await scrap()
    end = time.time() - start
    print(res, end)

@app.on_event("startup")
async def startup_event():
    # 将异步任务加入事件循环,不阻塞服务器启动
    asyncio.create_task(get_new_prices())

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

总结

核心问题就是asyncio.run()阻塞了主线程,导致Flask服务器无法正常启动。根据你的实际需求选择方案:简单场景用后台线程,需要任务调度用扩展,大量异步操作优先考虑FastAPI。

内容的提问来源于stack exchange,提问作者Evan Serg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:47:40