nginx防惊群核心靠机制设计而非进程退让:默认accept_mutex互斥锁控制接入权;高并发推荐reuseport内核级分发;配合cpu亲和性与multi_accept提升效率。

Nginx 多 Worker 进程本身不会“主动抢占”连接,真正需要防范的是新连接到达时多个 Worker 同时被唤醒、争抢 accept() 的“惊群效应”。避免这种无效竞争,核心不是靠进程自觉退让,而是靠机制设计让连接分发有序、低冲突。
accept_mutex 互斥锁控制接入权
这是 Nginx 默认启用的防惊群机制(1.11.3+ 版本默认 on):
- 仅当 epoll/kqueue 就绪通知触发且当前无积压连接时,Worker 才参与锁竞争
- 抢到锁的 Worker 在短时间内循环调用 accept(),收走所有就绪连接
- 其他 Worker 不会阻塞等待,而是继续处理已有连接或进入下一轮事件循环
- 锁释放后有 accept_mutex_delay(默认 500ms)冷却期,防止同一 Worker 连续霸占
reuseport 内核级连接分发(推荐高并发场景)
Linux 3.9+ 支持 SO_REUSEPORT,Nginx ≥1.9.1 可启用,它把分发逻辑下沉到内核:
- 每个 Worker 绑定同一端口时,内核按五元组哈希将新连接直接派发到对应 Worker 的 listen socket 队列
- 完全绕过用户态 accept_mutex,无锁、无唤醒竞争、分发更均衡
- 配置只需在 listen 指令后加 reuseport,例如:
listen 80 reuseport; - 启用后 accept_mutex 自动失效,建议显式设为 off
CPU 亲和性 + 进程数匹配物理核心
避免因调度混乱放大争抢感:
- worker_processes 设为物理核心数(非逻辑核数),例如 12 核机器设为 12
- 配合 worker_cpu_affinity auto;,让每个 Worker 独占一个物理核,减少缓存伪共享与上下文切换
- 若未绑定,多个 Worker 可能被调度到同一核心,看似“没抢连接”,实则在 CPU 层面激烈争抢算力
multi_accept 提升单次处理效率
减少锁持有频次,间接降低争抢密度:
- 开启 multi_accept on; 后,Worker 持锁期间会一次性收完 epoll 就绪队列中所有连接
- 相比每次只 accept 一个再释放锁,它缩短了锁占用时间,也减少了后续轮转中重复抢锁的次数
- 特别适合短连接、突发流量场景











