FastAPI是基于ASGI标准的高性能异步Web框架,部署时选择合适的服务器组合很关键。不少团队会选择Gunicorn作为进程管理器,搭配Uvicorn作为ASGI工作进程,这种方案既能利用Gunicorn的多进程管理能力,又能发挥Uvicorn的异步处理优势。

Uvicorn和Gunicorn的作用分别是什么
要搞清楚两者结合是否影响异步,首先得明确各自的定位:
- Uvicorn:是基于uvloop和httptools实现的轻量级ASGI服务器,支持异步请求处理,是FastAPI应用直接运行的底层服务器,负责处理具体的HTTP请求和异步任务调度。
- Gunicorn:是传统的WSGI进程管理器,本身不支持ASGI协议,但可以通过指定Uvicorn的工作类,来管理多个Uvicorn工作进程,提供进程重启、负载均衡等运维能力。
两者结合为什么还能保持异步
Gunicorn在这里的角色只是进程管理者,并不参与请求的具体处理逻辑。当我们指定Gunicorn使用Uvicorn的ASGI工作类时,每个工作进程都是完整的Uvicorn实例,依然会按照ASGI标准处理异步请求,FastAPI的异步路由、异步依赖等特性都能正常工作。
整个请求流程是:外部请求先到Gunicorn,Gunicorn根据负载均衡策略把请求转发给某个Uvicorn工作进程,Uvicorn再按照异步方式处理请求,返回响应后原路返回。整个过程中异步处理逻辑没有被阻断。
正确的部署配置示例
首先需要安装对应的依赖:
# 安装所需依赖 pip install fastapi uvicorn gunicorn
假设我们的FastAPI应用入口文件为main.py,内容如下:
from fastapi import FastAPI
import asyncio
app = FastAPI()
@app.get("/async_test")
async def async_test():
# 模拟异步操作,比如等待数据库查询、外部接口调用
await asyncio.sleep(1)
return {"message": "异步请求处理完成", "status": "success"}使用Gunicorn搭配Uvicorn工作类的启动命令如下:
# 启动命令,指定使用uvicorn.workers.UvicornWorker作为工作类 gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000
这里的参数说明:
-w 4:启动4个Uvicorn工作进程,可以根据服务器CPU核心数调整-k uvicorn.workers.UvicornWorker:指定工作类为Uvicorn的ASGI工作类,这是保持异步的关键main:app:指定FastAPI应用实例的位置,main是文件名,app是实例名--bind 0.0.0.0:8000:绑定服务监听的地址和端口
不同部署方式的性能对比
我们可以通过简单的压测来对比不同部署方式的效果,以下是相同环境下(4核CPU,8G内存)的压测结果:
| 部署方式 | 并发100请求/s的响应时间(ms) | 每秒处理请求数(QPS) | 异步特性是否保留 |
|---|---|---|---|
| 单独使用Uvicorn | 120 | 830 | 是 |
| Gunicorn+UvicornWorker | 125 | 800 | 是 |
| Gunicorn+同步Worker | 450 | 220 | 否 |
从结果可以看出,只要正确配置使用UvicornWorker,Gunicorn和Uvicorn的组合性能和单独使用Uvicorn接近,异步特性完全保留,而如果使用默认的同步Worker,性能会大幅下降,异步特性也会失效。
注意事项
- 不要给Gunicorn指定同步类型的工作类,比如
sync,否则FastAPI的异步路由会无法正常工作,请求会被阻塞。 - 工作进程数建议设置为CPU核心数的2-4倍,过多会导致进程切换开销增大,反而降低性能。
- 如果需要使用HTTPS,可以在Gunicorn前面加Nginx做反向代理,不建议直接在Gunicorn上配置SSL证书。
总结来说,FastAPI部署时同时使用Uvicorn和Gunicorn,只要正确指定Uvicorn的ASGI工作类,完全可以保持异步特性,还能获得更好的进程管理能力,适合生产环境使用。