worker_cpu_affinity的核心作用是避免进程迁移导致的缓存和TLB失效及NUMA跨节点访问延迟,需满足worker_processes为数字、掩码数与worker数一致、掩码位数不超CPU总数三个条件。

worker_cpu_affinity 的核心作用不是让单次请求变快,而是通过固定每个 worker 进程到特定 CPU 核心,避免 Linux 调度器频繁迁移进程——这种迁移会清空 L1/L2 缓存、刷新 TLB(Translation Lookaside Buffer),带来明显延迟抖动。尤其在高并发、长连接或 NUMA 架构下,效果更显著。
为什么上下文切换开销大
默认情况下,Linux 调度器会动态把 nginx worker 进程调度到任意空闲 CPU 上运行。但一个进程在不同核心间迁移时:
- L1/L2 缓存中积累的热点指令和数据全部失效,下次执行需重新加载
- TLB 中的虚拟地址→物理地址映射被清空,触发多次页表遍历
- 在 NUMA 系统中,若进程迁移到远端节点核心,还会引发跨节点内存访问,延迟翻倍
正确绑定的核心前提
配置生效必须同时满足三个硬性条件:
-
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% 而其他核空闲的情况
配套必须调的几项
单独开 worker_cpu_affinity 效果有限,需同步调整:
- 关闭
accept_mutex(1.11.3+ 默认已关):否则 worker 仍争抢 accept 锁,绑核也白绑 - 设好
worker_rlimit_nofile(如 65535)并同步配置系统 limits,否则连接数上不去 - 高并发建议开启
reuseport:让内核在 socket 层分发连接,彻底绕过用户态锁 - 避免多个 worker 绑到同一核心(如写成
0001 0001),等于人为制造争抢

















