Nginx 的 sendfile 与 tcp_nopush 不直接调节网卡队列,而是通过零拷贝和 TCP_CORK 机制使每次 TX 队列填充更饱满、更规律,降低中断频次与 softirq 开销;需配套禁用 gzip、tcp_nodelay off、确保 Content-Length 存在,并按 location 精细化启用。

在千兆或万兆局域网中,Nginx 的 sendfile 与 tcp_nopush 不直接调节网卡队列(如 RPS、RFS、XPS 或 ring buffer 大小),而是通过协同内核网络栈行为,间接影响网卡队列的填充效率和中断压力。真正决定网卡队列是否“堵”或“空转”的,是上层应用的数据推送节奏与内核发送缓冲区的配合程度——而这正是 sendfile + tcp_nopush 的作用边界。
为什么网卡队列不是 Nginx 配置能直接改的
Nginx 运行在用户空间,无法直接操作网卡硬件队列(如 Intel ixgbe 的 TX/RX ring buffer)或内核的软中断分发策略(RPS/RFS)。这些属于 Linux 网络子系统底层调优范畴,需通过 /proc/sys/net/core/ 和 /sys/class/net/eth0/queues/ 下的参数调整,例如:
-
net.core.netdev_max_backlog:控制未处理数据包在队列中的最大数量,千兆建议 ≥2500,万兆建议 ≥5000; -
net.core.rmem_max/wmem_max:影响 socket 接收/发送缓冲区上限,大文件传输时建议设为 4–16MB; -
/sys/class/net/eth0/queues/tx-0/xps_cpus:绑定 TX 队列到特定 CPU,避免跨核缓存失效; -
ethtool -G eth0 tx 4096 rx 4096:显式扩大 ring buffer 深度(需驱动支持)。
sendfile + tcp_nopush 如何减轻网卡队列压力
它们不“填满”队列,而是让每次入队的数据块更饱满、更规律,从而降低单位时间内的中断次数和上下文切换开销:
- sendfile on 触发零拷贝路径,跳过用户态内存拷贝,使内核可直接将磁盘页映射进 TCP 发送缓冲区,减少 CPU 占用和延迟;
- tcp_nopush on 启用 TCP_CORK,强制内核等待响应头 + 文件起始段(通常 ≤1 个 MTU,约 1460 字节)凑满后再推入网卡 TX 队列——避免大量 40–64 字节的小包反复触发 TX 中断;
- 二者联用后,一个大文件响应往往只需 1–3 次
sendfile()系统调用 + 对应的 TX 队列填充动作,而非数百次小 write(); - 实测显示:在万兆局域网中对 100MB 文件启用该组合,TX 中断频率可下降 40%–60%,尤其在高并发下载场景下,
softirq时间占比明显回落。
局域网环境下的关键配套设置
千兆/万兆带宽本身不是瓶颈,但错误配置会让高带宽变成“高丢包率”或“高重传率”。必须同步收紧以下环节:
- 禁用 gzip:压缩强制走用户态 read/write,彻底绕过 sendfile 路径;
- 显式设 tcp_nodelay off:避免与 tcp_nopush 冲突;Linux 下二者互斥,未关闭则 tcp_nopush 被静默忽略;
- 确保 Content-Length 存在:Nginx 需预知大小才能调用 sendfile();若上游返回 chunked,则退化为普通模式;
-
限制单次 sendfile 量:用
sendfile_max_chunk 512k,防止一次 push 过大阻塞 worker 事件循环,也适配多数首帧数据体积; -
按 location 精细化启用:只在服务真实静态大文件的位置开启,例如:
location ~ \.(mp4|zip|iso|dmg)$ { ... },不污染 API 或 WebSocket 路径。
验证是否对网卡队列产生正向影响
不能只看 Nginx 配置是否存在,要观察内核和网卡层面的实际行为:
- 运行
strace -e trace=sendfile -p $(pgrep nginx),确认 worker 进程确实在调用sendfile(); - 用
watch -n1 'cat /proc/net/dev'观察eth0的tx_compressed或tx_fifo_errors是否上升——稳定无增长说明 TX 队列未溢出; - Wireshark 抓包检查:HTTP 响应头与文件前 2KB 数据是否落在同一 TCP 报文段(即 “TCP segment of a reassembled PDU” 消失);
- 检查
nginx error.log,排除tcp_nopush is ignored类警告。


















