Worker数量需匹配应用类型与资源:I/O密集型可逐步增至6~8,CPU密集型不应超物理核心数;容器中须动态计算;gevent下应设2~3个worker并验证生效。

Worker数量不是设得越多越好,而是要匹配你的应用类型和服务器实际资源——设错会导致CPU空转、上下文切换飙升、内存耗尽,甚至比默认配置还慢。
怎么算出合理的--workers值
别直接套用 2 * CPU核心数 + 1。这个公式只在纯 I/O 密集、无阻塞调用、且系统无其他负载时才接近有效。现实中更稳妥的做法是:
- 从
--workers=4起步,压测(比如用wrk -t4 -c100 -d30s http://localhost:8000/health)看吞吐和延迟拐点 - 若应用大量依赖数据库、外部 HTTP 请求(如
requests.get())、文件读写,属于 I/O 密集型 → 可尝试逐步加到 6~8,再观察psutil.cpu_percent()是否持续高于 80%(说明开始争抢 CPU) - 若应用主要做图像缩放、数值计算、加密解密等,属于 CPU 密集型 →
--workers最好不超过 CPU 物理核心数,再多只会加剧上下文切换,反而降低单请求处理速度 - 在容器环境(Docker/K8s)中,
psutil.cpu_count()返回的是宿主机核数,必须用--workers $(( $(nproc) * 2 + 1 ))动态计算,或显式传入CPU_LIMIT环境变量控制
为什么--workers=16在4核机器上可能更慢
同步模式(--worker-class=sync)下,每个 worker 是独立进程,但 Python 的 GIL 和阻塞 I/O 会让它们大量时间“干等”。现象包括:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- CPU 使用率不高(比如平均 40%),但请求排队严重,
gunicorn日志里出现大量timeout: worker failed to boot或worker timeout -
top显示大量gunicorn: worker [xxx]进程处于S(sleep)状态,vmstat 1中cs(context switch)值飙升到 50k+/s - 内存占用线性增长,
ps aux --sort=-%mem | head -5发现多个 worker 占用数百 MB —— 每个进程都加载了完整应用代码和依赖 - 尤其当用了
--preload,所有 worker 共享同一份预加载的模块,但全局状态(如缓存字典、连接池实例)仍被各进程重复初始化,造成资源浪费
用gevent/eventlet时--workers该怎么设
换成协程模型后,并发能力不再靠堆进程数,而靠单 worker 内部的连接复用。这时 --workers 应大幅减少:
立即学习“Python免费学习笔记(深入)”;
- 优先设为
--workers=2或--workers=3,再配合--worker-class=gevent --worker-connections=1000 - 务必确认
gevent已安装,且启动时加--log-level debug,日志里必须看到Using worker: gevent—— 否则会静默降级回sync,你根本不知道没生效 - 检查是否漏了
gevent.monkey.patch_all():如果用了requests、urllib3、psycopg2等库,没 patch 就会退化成同步阻塞,协程完全不起作用 - 注意兼容性:某些 C 扩展库(如旧版
mysqlclient)不支持 gevent patch,会导致死锁或崩溃;可改用pymysql或升级驱动
容易被忽略的关键点
很多人调完 --workers 就以为结束了,但真正卡住性能的往往是配套参数没对齐:
-
--timeout默认 30 秒,但如果你的应用常调用超时较长的外部 API(比如支付回调),必须同步加大,否则 worker 会被主进程误杀重启 -
--keep-alive默认 5 秒,Nginx 侧若设了更长的keepalive_timeout,连接可能被 Gunicorn 先断开,导致客户端收到Connection reset by peer -
--max-requests和--max-requests-jitter是防内存缓慢泄漏的兜底手段,但不能替代排查真实泄漏源(比如未关闭的 SQLAlchemy session、全局 list 不断 append) - 所有调整必须在相同压测条件下对比:固定 QPS、相同请求体、关闭 Nginx 缓存,否则看到的差异可能是网络或代理层干扰


















