静态IO瓶颈根源是worker_processes与IO特性不匹配:进程过多引发磁盘随机寻道冲突,过少则CPU闲置;应按IO带宽而非CPU核心数调优,HDD建议2~4个、SSD可试8个,并同步调高文件描述符、somaxconn及启用sendfile/tcp_nopush。

静态 IO 竞争瓶颈常被误判为磁盘慢或带宽不足,实际根源往往是 worker_processes 与业务 IO 特性不匹配。Nginx 本身不缓存大文件,当大量小图、CSS、JS 被高频读取且总大小远超内存时,每个 worker 都会独立触发磁盘寻道——进程数过多,就会在底层产生大量随机 IO 冲突;过少,则单核饱和、其余 CPU 闲置。
先看你的负载类型:静态文件服务 ≠ 均匀 IO
不是所有静态场景都适合“设成 CPU 核心数”。关键区分两点:
- 文件规模:若网站静态资源总量(如图片库+前端包)明显大于可用内存(比如 64GB 内存但静态文件共 200GB),磁盘读取无法靠 page cache 缓解,IO 成为瓶颈主体
- 访问模式:是否大量并发请求分散在不同小文件上(如商品图、头像、图标)?这种模式下,单个 worker 在处理多个连接时会频繁切换读取位置,加剧磁盘寻道竞争
此时,单纯增加 worker 进程数反而放大 IO 冲突——多个进程同时发起随机读,硬盘响应延迟飙升,%wa(IO 等待)显著升高,而 CPU 利用率却不高。
推荐配置策略:按 IO 带宽而非 CPU 核心数来定
目标是让磁盘吞吐接近物理极限,又避免过度争抢。实测有效的做法:
- 从
worker_processes 1开始压测,观察iostat -x 1中的await和%util,确认单进程能否打满磁盘 IO - 逐步增加到 2、4、8,同步监控
iotop下各 nginx worker 的实际 IO BPS,若新增进程带来的增量 IO 微乎其微(比如提升<5%),说明已达 IO 瓶颈上限 - 对机械盘(HDD)环境,通常 2~4 个 worker 即可;SSD 可试到 8,但超过后
r/s(每秒读请求数)不再线性增长,反而avgqu-sz(平均队列长度)跳升,就是争抢信号
必须同步调优的配套项
worker_processes 不是孤立参数,以下三项不匹配,调再准也白搭:
-
系统文件描述符限制:运行
ulimit -n查当前值,确保worker_connections × worker_processes ≤ ulimit -n × 0.7(预留 30% 给日志、上游连接等) -
内核 listen 队列:执行
sysctl net.core.somaxconn,建议设为 65535,并在 nginxlisten指令后加backlog=65535 -
启用 sendfile + tcp_nopush:在
http或server块中加入
sendfile on;
tcp_nopush on;
tcp_nodelay on;
这能让内核直接 DMA 传输文件,绕过用户态拷贝,大幅降低 CPU 在静态文件分发中的开销
验证是否真解决:盯住三个指标
改完别只看 QPS,重点观察:
-
top中的 %wa 是否从 >30% 降到 -
ss -s输出里 “TCP: inuse” 和 “orphan” 数量是否稳定,无持续堆积 -
cat /proc/net/softnet_stat第一列(软中断处理数)是否不再随并发线性暴涨,说明网络收包压力已均衡

















