--workers非默认启用,仅在CPU利用率长期低于60%、存在同步阻塞或GPU显存闲置时才有效;须依物理核心数、内存/GPU容量及请求模式综合设定,并验证进程数、连接分布与CPU负载。

别直接套“2×CPU+1”,生产环境设错 --workers 常导致吞吐不升反降、OOM 或连接池爆满。
看 CPU 利用率再决定要不要加 worker
Uvicorn 单进程靠 async/await 已能扛住数千 I/O 请求。加 --workers 不是默认动作,而是对症下药:
- 压测时
htop显示 CPU 利用率持续低于 60%,但延迟飙升、QPS 卡住 —— 说明单核吃不满 - 代码里有
time.sleep(1)、requests.get()、pandas.read_csv()等同步阻塞调用 - 跑的是 GPU 推理服务(如 LLM 前处理),单 worker 只能串行发 batch,显存大量闲置
worker 数不能只看 nproc,得看三件事
真实取值由物理核心数、内存/GPU 显存容量、请求模式共同制约:
- 查物理核心数:
nproc输出为 4,--workers 4是安全起点;超过 8 后吞吐增长通常趋缓 - 看内存压力:每个 worker 是独立 Python 进程,加载一次大模型就占一份显存/CPU 内存;RTX 3060(12GB)实测最多稳住 4 个 worker
- 观察流量特征:如果请求极不均匀(例如每分钟集中来 100 个大 batch),worker 数宁少勿多,避免冷启动和空转开销
配完必须验证是否真生效
很多团队配了 --workers 8 却只看到 1 个 uvicorn 进程,常见失效原因:
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
- 同时启用了
--reload:二者互斥,--reload强制降级为单进程,且 fork 失败时静默回退 - 用 Gunicorn 做前置但漏写
-k uvicorn.workers.UvicornWorker:Gunicorn 默认起同步 worker,async def路由直接报TypeError: 'coroutine' object is not callable - Docker 容器未配 CPU quota:
docker run --cpus=2却设--workers 4,内核调度失灵,部分 worker 启动即被 kill - Windows 下 spawn 启动方式导致模块顶层代码重复执行,触发初始化冲突
验证三步走:ps aux | grep uvicorn | wc -l 必须等于你设的数值;lsof -i :8000 看连接是否分散到多个 PID;压测中盯住 top -p $(pgrep -f "uvicorn.*app"),主进程 CPU 应始终低于 5%。
多 worker 下数据库和缓存必须重设计
每个 worker 进程完全隔离,以下资源不是共享的:
- 模块级全局变量(比如
cache = {})—— 每个 worker 各有一份,数据不同步 - 数据库连接池(
DB_SOURCES中每个 worker 都持有一套独立池)—— 总连接数 =db_pool_size + db_max_overflow×APP_WORKERS,别超 MySQL 的max_connections -
lifespan的startup/shutdown会在每个 worker 里各执行一次 —— 别在这里发通知或初始化全局 cache
真正容易被忽略的点是:RuoYi-FastAPI 这类项目里,.env.prod 中的 APP_WORKERS 控制的是 uvicorn 启动参数,但它透传给 uvicorn 的前提是没被 Gunicorn 或 reload 覆盖 —— 很多人改了配置却没生效,卡在启动链路最前端。

















