worker_cpu_affinity通过sched_setaffinity()系统调用绑定worker进程到指定cpu核心,减少缓存失效与tlb刷新;worker_processes仅控制进程数量,不涉及绑定,二者必须配合使用才能提升高并发下的调度效率与响应稳定性。

Nginx 的 worker_processes 本身不直接调用 sched_setaffinity,它只是决定启动多少个 worker 进程;真正触发 CPU 绑定动作的是 worker_cpu_affinity 指令,其底层正是通过 Linux 的 sched_setaffinity() 系统调用实现的。
worker_processes 只管“数量”,不管“在哪跑”
该指令控制 Nginx 启动几个独立的 worker 进程,每个进程是单线程、事件驱动的。设为 auto 时,Nginx 读取 /proc/cpuinfo 中的物理核心数(非逻辑核),作为进程数依据。但它不做任何 CPU 分配决策——Linux 调度器仍可自由把某个 worker 迁移到任意核心上运行。
- 若只设
worker_processes 4却没配worker_cpu_affinity,4 个进程大概率被动态调度到不同核心间跳转 - 跳转会引发 L1/L2 缓存失效、TLB 刷新、SSL 会话缓存命中下降等隐性开销
- 尤其在高并发短连接场景下,这种抖动会明显拉高 p99 延迟
worker_cpu_affinity 才真正调用 sched_setaffinity
该指令在每个 worker 进程 fork 出来后、进入事件循环前,调用 sched_setaffinity() 把当前进程绑定到指定逻辑 CPU 上。Nginx 源码中对应函数是 ngx_set_cpu_affinity(),本质就是封装了标准系统调用:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 参数
pid = 0表示作用于当前进程(即刚 fork 的 worker) -
mask是一个位图,比如0001表示只允许在 CPU0 运行,0101表示允许在 CPU0 和 CPU2 - 配置
worker_cpu_affinity 0001 0010 0100 1000;就会让第 1~4 个 worker 分别独占 CPU0~CPU3
为什么必须配合使用才有效
单独调大 worker_processes 或只写 worker_cpu_affinity auto 都可能出问题:
-
auto模式下,Nginx 会按逻辑 CPU 数生成掩码,但超线程(HT)会导致逻辑核数翻倍;若物理核仅 8 个,逻辑核 16 个,auto可能分配到同一物理核的两个超线程上,共享 L1/L2 缓存反而争抢资源 - 容器环境中,cgroup 限制了可用 vCPU,
worker_processes auto仍会读宿主机的/proc/cpuinfo,导致进程数远超实际配额,引发严重争抢 - 正确做法是:先用
lscpu或cat /proc/cpuinfo | grep "cpu cores" | uniq确认物理核心数,再显式设置worker_processes N和对应 N 项的worker_cpu_affinity掩码
验证是否生效的小技巧
绑定成功后,可通过以下方式确认:
-
ps -eo pid,args,psr | grep nginx—— 查看每个 worker 进程固定在哪个逻辑 CPU(psr列) -
taskset -cp <pid></pid>—— 显示该进程当前允许运行的 CPU 列表 - 观察
/proc/<pid>/status</pid>中的Cpus_allowed_list字段










