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

tcp_nopush 本身不提升带宽上限,它的价值在于让内核把响应头和文件开头数据合并进更少的 TCP 报文发出,从而填满 MSS、减少小包数量、降低协议开销。要实现大文件传输的极致吞吐,关键不是单独打开 tcp_nopush,而是构建一条从磁盘/缓存直达网卡的零拷贝通路,并确保每个环节都为“攒包”让路。
必须同时启用 sendfile 和 tcp_nopush
tcp_nopush 是依赖 sendfile 的“配套动作”。没有 sendfile,它完全无效——Nginx 日志会明确提示 “tcp_nopush is ignored”。原因在于:
- sendfile 启用后,文件数据由内核直接从页缓存复制到 socket,响应头 + 文件首段被视为逻辑连续流,tcp_nopush 才能识别并合并
- 若走普通 read/write 模式(如开启 gzip、proxy_buffering、sub_filter 或动态生成内容),数据分段进入用户态缓冲区,tcp_nopush 失去作用基础
只在真实静态文件路径中启用
该优化仅对 Nginx 直接服务磁盘文件生效,典型场景包括:
- 使用 root 或 alias 指向本地目录,且请求后缀匹配大文件类型(如 .mp4、.zip、.iso、.tar.gz)
- 代理对象存储(如 MinIO、OSS)时,需设 proxy_buffering off,并确保 upstream 返回明确 Content-Length 和 200 响应
- 禁用所有干扰模块:gzip off、sub_filter off、ssi off、access_by_lua_block 移除——任何用户态处理都会切断零拷贝链路
配套参数必须严格对齐
tcp_nopush 不是独立开关,它需要底层行为协同才能真正攒包:
- tcp_nodelay off:显式关闭 Nagle 算法,避免它抢在“凑满 MSS”前强制发包;默认值虽为 off,但建议显式声明以防被上级块继承覆盖
- output_buffers 2 128k:增大发送缓冲区,默认 2×32k 对大文件常不够,易导致过早冲刷、破坏合并效果
- sendfile_max_chunk 512k:限制单次 sendfile 传输量,防止阻塞事件循环,也适配多数高清视频/安装包的起始段大小
按文件类型精细化配置,拒绝全局开启
对 API、HLS 的 m3u8、WebSocket 或小图资源启用 tcp_nopush 可能引入微小延迟,反而影响首屏体验。推荐写法:
location ~ \.(mp4|webm|avi|mov|zip|iso|tar\.gz|dmg)$ {
root /data/assets;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
gzip off;
output_buffers 2 128k;
sendfile_max_chunk 512k;
expires 7d;
add_header Cache-Control "public, immutable";
}
搭配 open_file_cache max=10000 inactive=30s 和 access_log off,可进一步降低高并发下的 I/O 与日志开销。










