手动指定 worker_cpu_affinity 掩码的核心目标是让每个 nginx worker 进程独占一个逻辑 cpu 核心,以优化缓存局部性、减少 tlb 刷新和跨 numa 访存开销;需严格对齐硬件拓扑、worker 数量与二进制位序,掩码组数必须等于 worker_processes,每组位数等于逻辑 cpu 总数,lsb 对应 core 0,验证须通过 ps、taskset 和 /proc/pid/status 确认绑定生效。

手动指定 worker_cpu_affinity 掩码,核心目标是让每个 Nginx worker 进程独占一个逻辑 CPU 核心,从而最大化 L1/L2 缓存局部性、减少 TLB 刷新和跨 NUMA 访存开销。这不是简单“填对数字”,而是要对齐硬件拓扑、进程数量与二进制位序。
确认逻辑 CPU 数量与位序规则
掩码有效性完全依赖于你对系统真实 CPU 拓扑的理解:
- 运行
nproc或lscpu | grep "CPU(s):"获取逻辑 CPU 总数(含超线程) - 用
cat /sys/devices/system/cpu/online查看启用的核心范围,例如0-7表示共 8 个逻辑核,编号为 0~7 - 掩码中**最右一位(LSB)对应 core 0**,向左依次为 core 1、core 2……因此 4 核机器的
0001表示只允许使用 core 0,1000表示只允许使用 core 3 - 若 BIOS 关闭了超线程,逻辑核数 = 物理核数;若开启,则需注意是否要避开超线程对(如仅用 0/2/4/6 而非 0/1/2/3)
按核数逐级写出标准掩码格式
掩码组数必须严格等于 worker_processes 数量,每组位数等于逻辑 CPU 总数。常见配置如下:
-
2 核服务器:设
worker_processes 2;,配worker_cpu_affinity 01 10;(worker 0 → core 0,worker 1 → core 1) -
4 核服务器:设
worker_processes 4;,配worker_cpu_affinity 0001 0010 0100 1000; -
8 核服务器:设
worker_processes 8;,配worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; - 也可用十六进制简写(等价):
01 02 04 08 10 20 40 80,更紧凑且不易数错位
规避常见掩码陷阱
错误掩码不仅无效,还可能导致启动失败或性能反降:
- 掩码组数 ≠
worker_processes值:Nginx 直接拒绝启动,报错 “invalid number of masks” - 重复使用同一掩码(如
0001 0001):两个 worker 共享 core 0,引发锁争抢和缓存抖动 - 位数不匹配(如 8 核系统写了 4 位掩码
0001):高位被截断,实际绑定行为不可控 - 在容器或 KVM 虚拟机中未透出完整 topology:
auto可能误判,但手动掩码若照搬宿主机配置,极易超出虚拟 CPU 范围
验证是否真正生效
配置后必须验证,不能只信配置文件:
- 重启 Nginx 后,执行
ps -eo pid,args,psr | grep 'nginx: worker',观察各 worker 的psr列是否稳定落在预期核心上 - 取任一 worker PID,运行
taskset -cp PID,输出应显示类似pid 12345's current affinity list: 0 - 检查
/proc/PID/status | grep -i "cpus_allowed_list",确认值为单个数字(如0),而非范围或多个值 - 若发现多个 worker 显示相同 core ID,说明掩码重复或
worker_processes设置过大
压榨缓存吞吐上限的关键,在于让每个 worker 长期驻留同一核心——这样指令与数据能反复命中 L1 指令缓存、L1 数据缓存及共享 L2,避免每次调度都清空流水线。手动掩码虽稍费事,但控制粒度最准,尤其适合 NUMA 架构或需隔离后台任务的生产环境。










