替换time.sleep为asyncio.sleep后FastAPI仍串行执行问题
FastAPI异步接口串行问题解决
问题核心原因
你看到的串行执行,本质是测试方式不对。如果用浏览器、单窗口curl这类工具串行发送请求,前一个请求没完成时,后一个请求根本没被发起,自然会按顺序执行。异步接口的并发能力,必须在同时发起多个请求的场景下才能体现。
验证并发效果的方法
用并发工具发起请求,比如写个简单的Python并发脚本:
import aiohttp import asyncio async def fetch(session, url): async with session.get(url) as response: return await response.json() async def main(): async with aiohttp.ClientSession() as session: # 同时发起3个请求 tasks = [fetch(session, "http://127.0.0.1:8501/ping") for _ in range(3)] results = await asyncio.gather(*tasks) print(results) if __name__ == "__main__": asyncio.run(main())
运行这个脚本后,服务端日志会变成:
Hello Hello Hello bye bye bye INFO: 127.0.0.1:xxxx - "GET /ping HTTP/1.1" 200 OK INFO: 127.0.0.1:xxxx - "GET /ping HTTP/1.1" 200 OK INFO: 127.0.0.1:xxxx - "GET /ping HTTP/1.1" 200 OK
这就说明异步并发已经生效。
额外说明
- FastAPI的
async def接口运行在Uvicorn的事件循环中,当遇到await asyncio.sleep()这类可等待对象时,事件循环会暂停当前任务,转而去处理其他等待中的请求,直到sleep完成再回来继续执行当前任务。 - 如果是用
def定义的同步接口,Uvicorn会用线程池处理请求,但异步接口是在单线程事件循环内实现并发,资源利用率更高。
内容的提问来源于stack exchange,提问作者Federico
相关产品推荐
相关产品推荐

