FastAPI中async的实际作用是什么?为何异步与同步代码表现相似?
关于FastAPI异步与同步接口性能疑惑的解答
我编写了两段FastAPI代码:
第一段异步实现代码:
from fastapi import FastAPI import asyncio app = FastAPI() @app.get("/") async def root(): a = await asyncio.sleep(10) return {'Hello': 'World',}
第二段同步实现代码(未使用async关键字):
from fastapi import FastAPI import time app = FastAPI() @app.get("/") def root(): a = time.sleep(10) return {'Hello': 'World',}
原本以为异步代码的优势是可同时处理多个连接,但测试后发现同步代码也能做到,两者表现和性能一致,不清楚为何要使用async方法,恳请解答。
解答
你测试时感觉两者表现一致,核心原因是FastAPI会自动为同步函数启用线程池:当你用time.sleep(10)这种不占用CPU的阻塞操作时,线程池里的每个线程会在sleep期间让出CPU资源,让其他线程可以处理请求,所以看起来和异步协程的效果差不多。
但两者的差异在特定场景下会非常明显:
- IO密集型任务且能使用异步库时:如果你的接口需要调用异步数据库驱动、异步HTTP客户端这类工具,异步代码可以直接通过
await让协程在等待IO结果时让出CPU,不需要额外创建线程,能更高效地利用服务器资源,同时处理更多并发请求。而同步函数调用异步库需要额外的线程或进程适配,反而麻烦。 - CPU密集型任务:这种场景下两者差异不大,因为Python的GIL锁限制了同一时间只有一个线程执行CPU密集操作,异步协程也没办法绕过GIL,这时候同步代码反而更简单直接。
- 资源占用:异步协程的开销远小于线程,当并发量极大时,异步架构能支撑更多请求,而线程池的线程数量有上限(默认FastAPI的线程池大小是CPU核心数*5),超过上限后新请求会排队,性能会下降。
简单说:如果你的接口大部分是等待外部资源(比如数据库、API)的IO操作,用异步+异步库能最大化性能;如果是纯计算或简单阻塞操作,同步代码足够用。
内容的提问来源于stack exchange,提问作者filtertips
相关产品推荐
相关产品推荐

