防范worker进程争抢单核cpu的关键是启动前就让每个worker严格运行在独立物理核上,需先用lscpu确认物理核数、设worker_processes为物理核数、用worker_cpu_affinity auto自动跳过超线程核,并关闭accept_mutex、开启multi_accept、绑定网卡软中断,最后通过ps、taskset和mpstat验证绑定生效。

防范 Worker 进程争抢单核 CPU 的关键,不是事后调优,而是从启动前就切断争抢路径——让每个 worker 严格运行在独立物理核上,彻底规避缓存争用、TLB 刷新和执行单元冲突。
确认真实物理核数,绕开超线程干扰
逻辑核 ≠ 算力。超线程会让一个物理核暴露为两个逻辑 CPU(如 8 物理核 + HT = 16 逻辑核),但 L1/L2 缓存、执行单元是共享的。两个 worker 绑在同一个物理核的不同逻辑 ID 上,反而会相互拖慢。
- 运行 lscpu | grep -E "Core(s) per socket|Socket(s)",算出物理核心总数(例如:2 sockets × 6 cores = 12)
- 再用 nproc 或 lscpu | grep "CPU(s):" 查逻辑核总数(如显示 24,说明 HT 已启用)
- worker_processes 必须设为物理核数(如 12),而非逻辑核数(24)
用 auto 模式精准绑定,避免手动掩码出错
手动写二进制或十六进制掩码极易位序错位、长度不匹配、跨 NUMA 节点——这些都会导致部分 worker 失去控制,静默退回到默认调度。
Nginx是一款高性能的开源软件,由俄罗斯开发者Igor Sysoev于2004年创建。它最初设计为高效的HTTP Web服务器,现已成为最受欢迎的Web服务器之一。Nginx以事件驱动、非阻塞I/O架构著称,能以极低内存占用处理数万并发连接,特别适合高流量场景。它同时担任反向代理、负载均衡器、HTTP缓存、TCP/UDP代理等多重角色,常用于静态文件服务、SSL终止、请求转发、API网关和微服务
- Nginx ≥ 1.9.10 支持 worker_cpu_affinity auto;,它自动跳过超线程对称核,按物理核顺序分配,L1/L2 缓存局部性最优
- 若需限定范围(如容器中只分配前 4 个逻辑 CPU),可用 worker_cpu_affinity auto 00001111;
- 切忌混用:worker_processes 8 却只给 4 组掩码值,剩余 worker 将 fallback,争抢风险照旧
同步关闭干扰项,防止“绑住了却还在排队”
只配 worker_cpu_affinity 不调其他参数,等于给跑车装定速巡航却踩着刹车——进程被绑住,但仍在等锁、一次只收一个连接、软中断在隔壁核收包再搬运过来。
- accept_mutex off;:关闭连接接入串行锁(Nginx ≥ 1.11.3 默认已关,旧版本务必显式关闭)
- multi_accept on;:让每个 worker 一次从内核事件队列取多个就绪连接
- 把网卡软中断也绑到相同物理核:查 cat /proc/irq/*/smp_affinity_list,用 echo 将对应 IRQ 绑到同组 CPU
验证是否真生效,别信配置信运行态
配置写完不验证,等于没做。高频争抢往往表现为 CPU 利用率不高但延迟飙升、P99 波动剧烈——这正是多个 worker 挤在同一核上反复切换的典型症状。
- 查实际运行核:ps -eo pid,psr,comm | grep 'nginx: worker' | sort -k2,2n,每个 PID 应对应唯一且连续的 PSR 值(如 0、1、2、3)
- 查绑定状态:taskset -cp $(pgrep -f "nginx: worker" | head -1),输出应为类似 pid XXXX's current affinity list: 2
- 观察负载下 mpstat -P ALL 1,各物理核利用率应均衡,无单核持续 95%+ 且其余核闲置现象










