Nginx性能优化需使buffer大小为系统页大小(如4KB或2MB大页)整数倍,以减少内存碎片和TLB压力;同时协同内核参数(如THP、swappiness)、TCP栈(MSS对齐、fastopen)、socket队列及NUMA绑定,实现内存、网络与CPU的全栈对齐。

要让 Nginx 真正跑满硬件潜力,光调配置不够——必须让它的内存读写行为与 Linux 内核的页管理、TCP 栈、文件系统缓存对齐。这不是“加参数”就能解决的事,而是让 Nginx 的 块级操作单位(如 sendfile、buffer、keepalive 单位)和内核的 底层调度粒度(如 page size、sk_buff 大小、socket 缓冲区切片)形成协同节奏。核心目标是:减少跨层拷贝、避免缓冲区错配导致的碎片重传、压制 TIME_WAIT 堆积引发的端口争抢,并把延迟抖动压到最低。
对齐内存页与 buffer 分配单元
Nginx 默认的 client_header_buffer_size(1k)、large_client_header_buffers(4×4k)等值,应与系统默认 page size(通常 4KB)保持整数倍关系。若用大页(hugepage),则需同步调整:
- 启用透明大页(不推荐用于高并发短连接)或显式分配 2MB hugepage:echo 128 > /proc/sys/vm/nr_hugepages
- 在 nginx.conf 中将 proxy_buffer_size、client_body_buffer_size 等设为 2M 或其子倍数(如 512k、1M),避免 buffer 跨页分裂
- 配合 vm.swappiness=1(非 0),既防 swap 又允许内核在内存压力下优先回收 page cache,而非 kill worker 进程
匹配 TCP 段大小与网卡 MSS
Nginx 的 tcp_nopush 和 sendfile 行为高度依赖 TCP 层的段封装逻辑。若内核未对齐网卡实际 MSS(如千兆网卡典型 MSS=1448),就会触发多次小包发送或 Nagle 与 delayed ACK 的冲突:
- 确认物理链路 MSS:ss -i | grep mss,取最小值(如 1448)
- 设置 nginx 的 client_header_buffer_size ≤ MSS,large_client_header_buffers 总容量 ≥ 2×MSS(防首包截断)
- 启用 tcp_fastopen=3(客户端+服务端双向加速握手),并确保 listen 指令含 fastopen=256(backlog 同时生效)
- 禁用 tcp_tw_recycle(已废弃且在 NAT 场景下引发时间戳错乱),仅保留 tcp_tw_reuse=1 + tcp_fin_timeout=30
协同 socket 队列与事件模型深度
epoll 并非万能——它只管就绪通知,真正吞吐瓶颈常卡在内核 socket 接收队列(sk_receive_queue)和应用层读取节奏之间:
- net.core.somaxconn 和 nginx listen backlog 必须一致(如都设为 65535),否则 min(somaxconn, backlog) 成硬上限
- net.core.netdev_max_backlog 应 ≥ somaxconn,防止网卡中断来不及处理导致丢包
- worker_connections × worker_processes 不得超过 ulimit -n(建议设为 1000000),且需在 /etc/security/limits.conf 中对 nginx 用户单独限制
- 启用 multi_accept on,使单次 epoll_wait 触发后,worker 尽可能多地 accept(),减少事件循环空转
绑定 CPU 与 NUMA 内存域
现代多路服务器存在显著的 NUMA 差异。若 Nginx worker 在 CPU0 上运行,却频繁访问远端节点内存(如 /var/cache/nginx),延迟可翻倍:
- 用 lscpu 查 NUMA topology,确定每个 CPU core 对应的 local memory node(如 node0 绑定 core 0–7)
- 在 systemd service 中配置 CPUAffinity=0-7 和 MemoryNodes=0,或用 numactl --cpunodebind=0 --membind=0 nginx
- 若用 openresty,可在 init_by_lua_block 中调用 ngx.config.cpuinfo() 辅助动态绑定
- 关闭无关服务的 IRQ balance,固定网卡中断到同 NUMA 节点的 CPU 上(echo 1 > /proc/irq/*/smp_affinity_list)


















