tcp_nopush必须与sendfile协同生效:前者依赖后者提供的内核零拷贝路径,将响应头与文件首段合并发送以减少小包;单独启用无效,且需关闭gzip、确保content-length、按文件类型精准配置。

tcp_nopush 必须和 sendfile 配合使用才能生效,单独开启 tcp_nopush 没有效果。它的作用不是“延迟发送”,而是让内核把响应头和文件开头的数据尽可能合并进同一个 TCP 报文段发出,从而减少小包数量、提升单包载荷率,特别适合图片、视频、安装包等大体积静态资源的分发。
必须同时启用 sendfile 和 tcp_nopush
sendfile 是零拷贝的基础:它让内核直接从磁盘描述符复制数据到 socket 描述符,跳过用户态内存拷贝;tcp_nopush 正是依赖这条内核直通路径,才能识别并合并响应头与首段文件数据。
- 在 http、server 或 location 块中都需显式写明:sendfile on; 和 tcp_nopush on;
- 若仅开 tcp_nopush 而 sendfile 为 off,Nginx 日志会提示 “tcp_nopush is ignored”
- 推荐设置 sendfile_max_chunk 512k:避免单次 sendfile 过大阻塞事件循环,也适配多数高清图/短视频的前段大小
只对真实静态文件路径启用
该优化仅在 Nginx 直接服务磁盘文件(如用 root 或 alias 指向本地路径)时触发,proxy_pass、FastCGI、gzip 压缩或动态生成内容均不走此路径。
- 按后缀精准控制,例如图片:location ~* \.(jpg|jpeg|png|webp|avif|gif)$
- 视频/大文件:location ~ \.(mp4|webm|zip|iso|tar\.gz)$
- 务必关闭 gzip:gzip off; —— 否则强制进入用户态压缩流程,sendfile 自动禁用
配套参数必须对齐
tcp_nopush 的“攒包”行为需要内核有等待空间,而 tcp_nodelay 控制是否绕过 Nagle 算法。二者逻辑上互斥,必须协调配置。
- tcp_nodelay off;(默认即为 off):允许内核暂存数据,等待凑满 MSS 再发,使 tcp_nopush 有机会合并
- 若设为 on,则强制立即发包,直接抵消 tcp_nopush 效果
- 确保响应头含 Content-Length:Nginx 需预知文件大小才启用 sendfile 路径;对象存储直传或后端服务需返回明确长度,避免退化为 chunked 编码
其他关键辅助配置
光靠两个指令不够,还需减少干扰项、提升底层支撑能力。
- 静态资源 location 中加 access_log off;:避免日志写入成为高并发下的 I/O 瓶颈
- 启用文件句柄缓存:open_file_cache max=10000 inactive=30s; 减少 stat()/open() 系统调用
- 若用 proxy_pass 中转(如回源 CDN),需设 proxy_buffering off; 且 proxy_http_version 1.1;,并确认 upstream 返回 Content-Length










