最稳妥方案是使用 worker_cpu_affinity auto,它自动按物理核分配、避开超线程,适配i/o密集且偶有cpu热点的高并发反向代理场景。

直接用 worker_cpu_affinity auto 就行,这是目前最稳妥、适配性最强的方案,尤其适合反向代理这类 I/O 密集又偶有 CPU 热点的高并发场景。
为什么绑定能压降上下文切换
Nginx worker 进程本身轻量,但高频处理 SSL 握手、header 解析、gzip 压缩、连接复用等操作时,Linux 默认调度器容易将其在不同核心间来回迁移。每次迁移都会触发完整进程上下文切换:
- 寄存器状态保存/恢复
- TLB(地址转换缓冲区)刷新
- L1/L2 缓存失效
实测中,未绑定时每秒上下文切换(cs)常超 50 万次,L1 缓存命中率可能从 95% 骤降至 60%,延迟抖动明显增大。绑定后,每个 worker 固定运行在单一物理核上,热点数据(如 SSL session cache、共享内存 slab)持续驻留本地缓存,避免跨核迁移开销。
怎么配才真正生效
配置要起作用,必须同时满足三个硬性条件:
-
worker_processes 必须设为数字,比如
worker_processes 4;;若写auto,则必须搭配worker_cpu_affinity auto -
掩码数量必须与 worker 数量严格一致:4 个 worker 就得提供 4 个二进制掩码,如
0001 0010 0100 1000 -
每个掩码的位数不能超过系统逻辑 CPU 总数,可用
nproc或lscpu | grep "CPU(s)"先确认
推荐写法:按场景选最稳的
不必手算二进制,优先用语义清晰、容错性强的方式:
- 物理 4 核服务器:
worker_processes 4;+worker_cpu_affinity 0001 0010 0100 1000; - 8 核以上且不想出错:
worker_cpu_affinity auto;(Nginx 1.9.10+ 支持),自动跳过超线程对称核,按物理核顺序分配 - 只想启用前 4 个物理核:
worker_cpu_affinity auto 00001111;,后缀十六进制掩码限定可用范围 - 虚拟机或容器环境:优先用
auto配合 cgroup 限频/配额;硬绑定反而可能因宿主机调度失准导致负载不均
验证是否真的绑上了
别只看配置文件,运行起来再确认:
- 查各 worker 当前在哪颗核运行:
ps -eo pid,args,psr | grep 'nginx: worker'—— 第三列psr应是 0、1、2、3…一一对应 - 查某进程允许跑的 CPU 列表:
taskset -cp <pid></pid>—— 输出类似pid 12345's current affinity list: 2表示只允许在 CPU 2 运行 - 压测时观察
mpstat -P ALL 1:各核利用率应相对均衡,没有某核长期 100% 而其他核空闲的情况











