tcp_nopush必须与sendfile协同生效,仅对静态文件零拷贝传输有效;需禁用gzip、显式配置tcp_nodelay off、output_buffers和sendfile_max_chunk,并按文件类型精细化启用。

优化 Nginx 的 tcp_nopush 配置,核心不是“单独调这个参数”,而是让它和 sendfile 协同工作,在合适场景下减少小包、合并传输,从而降低网络碎片。它本身不加速带宽,但能提升单连接吞吐效率,尤其对大静态文件有效。
必须满足的前置条件
没有这些基础,tcp_nopush 就是摆设:
-
启用
sendfile on:这是前提中的前提。只有走内核零拷贝路径(如直接从磁盘页缓存发文件),tcp_nopush才能起作用;proxy_pass、gzip 压缩、body_filter 等都会绕过该路径,使其失效。 -
禁用
tcp_nodelay(或确保其为 off):二者逻辑冲突。tcp_nodelay on强制立即发包,会直接抵消tcp_nopush的“攒包”行为。现代 Nginx(1.15+)虽支持部分共存,但对大文件分发,明确设tcp_nodelay off更稳妥。 - 只在适用场景启用:它对视频、ISO、安装包等 >100KB 的静态资源效果明显;对小文件(如 HTML、图标)、HTTPS 流量、动态响应基本无效,甚至可能轻微增加首字节延迟。
推荐的配置位置与写法
不建议全局开启,应按需下沉到具体服务块:
-
在
http块统一启用(适合全站以静态资源为主):
sendfile on;<br>tcp_nopush on;<br>tcp_nodelay off;
-
更精准:限定在
location块中(推荐),例如只对视频或下载目录生效:
location ~ \.(mp4|avi|iso|zip|tar\.gz)$ {<br> root /data/files;<br> sendfile on;<br> tcp_nopush on;<br> tcp_nodelay off;<br>}
配合其他关键调优项
单靠 tcp_nopush 效果有限,需组合发力:
-
设置
sendfile_max_chunk 512k:避免单次 sendfile 阻塞 worker 进程,也利于内核更高效组装大包。 -
关闭无关日志:对大文件 location 加
access_log off;,避免 I/O 成为瓶颈。 -
启用文件句柄缓存:
open_file_cache max=10000 inactive=30s;减少重复 open/stat 系统调用。 - 合理控制响应头大小:过大的自定义 header 可能挤占 TCP 包空间,影响“头+数据”合并效果。
如何验证是否真正生效
不能只看配置是否写对,要观察实际网络行为:
- 用
ss -i查看活跃连接,确认输出中有np(即 nopush 标记); - 用 Wireshark 抓取响应流量,对比开启前后:理想情况下,HTTP 响应头与文件开头几百 KB 数据应落在同一个 TCP 段中(而非拆成多个小包);
- 压测时关注“小于 1500 字节的 TCP 包占比”是否下降,重传率是否稳定。
本质上,tcp_nopush 是一个面向内核发送队列的精细控制开关,不是魔法加速器。配得对,它让每个包都更“实在”;配错了,它就安静地待在那里,不起作用也不报错。


















