必须用gunicorn调用uvicorn.workers.UvicornWorker,否则FastAPI异步路由退化为同步、await失效、QPS降至单进程uvicorn的1/3;因FastAPI是ASGI应用而gunicorn默认syncworker仅支持WSGI协议,无法解析ASGI的scope/receive/send三元组。

为什么不能直接用 gunicorn 启动 FastAPI
因为 FastAPI 是 ASGI 应用,而 gunicorn 默认用的是 syncworker,只认 WSGI 协议。它根本解析不了 ASGI 的 scope/receive/send 三元组——结果就是:await 不执行、异步路由被阻塞、压测时连接堆积、QPS 掉到单进程 uvicorn 的 1/3 左右,甚至报 RuntimeWarning: coroutine 'xxx' was never awaited 或直接 500。
uvicorn.workers.UvicornWorker 是唯一能跑通的 worker 类型
必须显式指定这个 worker,才能让每个 gunicorn 子进程内部真正启动一个 uvicorn 实例,完整接管 ASGI 生命周期。常见错误包括:
- 写成
-k uvicorn.worker.UvicornWorker(少了个s)→ 报ImportError: cannot import name 'UvicornWorker' - 用
--worker-class但漏了uvicorn[standard]依赖 → 启动时报ModuleNotFoundError: No module named 'uvicorn.workers' - 配置文件里写
worker_class = "uvicorn.workers.UvicornWorker",但没装uvicorn到全局或虚拟环境 →gunicorn加载失败,日志只在errorlog里有提示
main:app 这个路径到底怎么写才对
冒号前是 Python 模块路径(不含 .py),冒号后是模块内定义的 FastAPI 实例变量名。验证方式最可靠:
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
- 在项目根目录下运行
python -c "from main import app; print(app)",能成功 import 就说明路径和变量名没问题 - 如果入口是
src/app/main.py,且app变量定义在该文件中,要确保src在PYTHONPATH里,或启动时加--chdir /path/to/project - 常见翻车点:
main.py里写的是fastapi_app = FastAPI(),却运行gunicorn main:app→ 应该是main:fastapi_app
进程数不是越多越好,workers 要按负载类型调
公式 (2 * cpu_count) + 1 在 I/O 密集型服务(如调外部 API、数据库查询)里可能有用,但对 CPU 密集型(如模型推理、图像处理)反而会因 GIL 和内存开销拖慢整体吞吐。实测中:
- 8 核 CPU + 纯 CPU 计算型服务:6~8 个
workers更稳,再往上 CPU 利用率不升反降 - 8 核 + 混合型(含 GPU 推理):需同步控制
gunicorn进程数和模型加载策略,否则显存被多个进程重复占满 - 必须用
ps aux | grep uvicorn或lsof -i :8000确认实际生效的进程数,别只信配置文件里的数字
真实部署时最容易忽略的,是 uvicorn.workers.UvicornWorker 对 uvicorn 版本的隐式要求——比如 uvicorn 0.52.1 才稳定支持 max_connections 参数,旧版本设了也无效;还有 --preload 开关,看似省资源,但会提前加载所有模块,导致环境变量读取失败或模型重复初始化。这些细节不验证,上线后就只能靠日志猜问题。









