Uvicorn的--workers仅在CPU密集或同步阻塞场景下有效,设错反降吞吐;常见单进程原因:Gunicorn未配uvicorn.workers.UvicornWorker、Uvicorn与Gunicorn同时设workers、混用--reload;数值需依CPU核数、内存/显存、请求节奏综合确定,且startup/shutdown事件各worker独立执行。

Uvicorn 的 --workers 不是“开越多越快”,设错反而拖垮吞吐——它只在同步阻塞、CPU 密集或 GPU 利用率低时才值得启用,且必须匹配 CPU 核数、内存容量和请求节奏。
为什么加了 --workers 却只看到 1 个进程?
启动后 htop 或 ps aux | grep uvicorn 仍只显示一个主进程?大概率掉进这三个坑:
- 你在用
gunicorn做前置,但没配worker_class="uvicorn.workers.UvicornWorker"—— 缺这个,Gunicorn 默认起的是同步 worker,async def路由直接报TypeError: 'coroutine' object is not callable - 同时写了
gunicorn ... --workers N又写了uvicorn ... --workers M—— Uvicorn 自身的--workers在 Gunicorn 下会被忽略,只认 Gunicorn 的配置 - 命令里混用了
--reload—— 多进程模式下--reload会失效(甚至被自动禁用),因为文件监控与 fork 冲突
--workers 数值怎么定?别套公式
所谓 “2×CPU 核数 + 1” 是误导。真实取值取决于三件事,缺一不可:
-
nproc查出 CPU 核数:4 核机器,--workers 4是安全起点;超过 8 后吞吐增长通常趋缓 - 内存/显存总量:每个 worker 是独立 Python 进程,加载一次大模型就占一份显存。RTX 3060(12GB)最多扛住 4 个 worker,再多必
OOM - 请求模式:如果流量极不均匀(比如每分钟集中来 100 个大 batch),worker 数宁少勿多,避免空转开销吃掉 CPU
压测时观察两个指标:CPU 利用率长期低于 60% 但 QPS 上不去 → 说明单进程没吃满多核,该加 worker;QPS 反而下降 + 进程频繁重启 → 很可能内存或显存已爆。
多 worker 下哪些东西不能共享?
每个 worker 是独立进程,内存完全隔离。以下写法会出问题:
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
- 用全局变量(如
cache = {})存状态 → 每个 worker 各有一份,数据不一致、内存翻倍 - 依赖
threading.local()或单例类做上下文 → 进程间不传递,等同于失效 - 在
@app.on_event("startup")里加载大模型 → 每个 worker 都加载一遍,显存直接 ×N
正确做法:状态存 Redis / 数据库;模型加载逻辑改用 lazy init 或由主进程预加载后通过共享内存(如 mmap)分发;若必须进程内缓存,用 functools.lru_cache 并控制 maxsize。
和 Gunicorn 配合时,--workers 归谁管?
当用 gunicorn -k uvicorn.workers.UvicornWorker 时,Uvicorn 自身的 --workers 参数被完全忽略。真正生效的是 Gunicorn 的 --workers 和 --worker-class:
gunicorn main:app \ --workers 4 \ --worker-class uvicorn.workers.UvicornWorker \ --bind 0.0.0.0:8000 \ --timeout 120
此时每个 Gunicorn worker 都是一个完整 Uvicorn 实例,自带 asyncio 事件循环。注意:Gunicorn 的 --workers 值同样受 CPU/内存约束,且不要盲目设高 —— 每个 Uvicorn worker 本身已是异步并发体,开太多反而增加进程调度开销。
最易被忽略的一点:多 worker 模式下,startup 和 shutdown 事件每个进程各执行一次。如果你在 startup 里初始化数据库连接池、加载模型或连 Kafka,得确认这些操作是否支持多实例并发执行,否则可能触发连接冲突或重复注册。

















