如何让FastAPI同时处理多个请求?
FastAPI无法同时处理多个请求的问题
我遇到一个问题:FastAPI在处理某个请求时,无法响应其他任何请求。我期望它能够同时处理多个请求,因为会有多名用户访问该REST API。
异步流程最小示例
启动服务器:uvicorn minimal:app --reload,运行request_test并执行test()后,能得到预期返回结果{'message': 'Done'}。但如果在第一个请求的20秒窗口期内再次执行test(),第二个请求要等到第一个请求的sleep_async执行完成后才会被处理。
无异步流程场景
即使不使用异步调用,直接在async def info中等待,也会出现同样的问题,这让我无法理解。
FastAPI代码:minimal
#!/usr/bin/env python3 from fastapi import FastAPI from fastapi.responses import JSONResponse import time import asyncio app = FastAPI() @app.get("/test/info/") async def info(): async def sleep_async(): time.sleep(20) print("Task completed!") asyncio.create_task(sleep_async()) return JSONResponse(content={"message": "Done"})
测试代码:request_test
#!/usr/bin/env python3 import requests def test(): print("Before") response = requests.get(f"http://localhost:8000/test/info") print("After") response_data = response.json() print(response_data)
问题原因与解决方法
核心问题出在你用了同步阻塞的time.sleep(20),它会直接卡住FastAPI依赖的异步事件循环,导致整个线程被占用,其他请求根本没机会被处理。
解决办法1:使用异步睡眠替换同步睡眠
把time.sleep(20)换成异步的await asyncio.sleep(20),这样事件循环在等待时会释放控制权,去处理其他请求。修改后的代码如下:
async def sleep_async(): await asyncio.sleep(20) # 替换time.sleep为asyncio.sleep print("Task completed!")
解决办法2:将同步操作移到线程池(如果必须用同步代码)
如果你的业务逻辑必须依赖同步阻塞操作(比如无法替换的第三方同步库),可以用asyncio.to_thread把它放到单独的线程里执行,避免阻塞事件循环:
async def sleep_async(): await asyncio.to_thread(time.sleep, 20) # 把同步操作丢到线程池 print("Task completed!")
补充说明
FastAPI的异步端点本质是基于单线程的事件循环工作的,只有当所有操作都是非阻塞的异步操作时,才能同时处理多个请求。一旦有同步阻塞代码占用了事件循环线程,整个服务就会“卡住”,直到这个阻塞操作完成。
内容的提问来源于stack exchange,提问作者Xaver
相关产品推荐
相关产品推荐

