tcp_nopush 必须与 sendfile 协同启用才有效,单独开启无效;其核心是减少小包、提升单包载荷率,适用于首屏快、带宽高、延迟适中的高清图片等大体积静态资源分发场景。

tcp_nopush 本身不直接提升小文件分发效率,它和 sendfile 协同作用时,真正受益的是大体积静态资源(如高清图片、视频、安装包),而非“海量静态小文件”。对小文件(比如几 KB 的图标、ico、小 JS/CSS),开启 sendfile + tcp_nopush 不仅无效,还可能因机制错配导致性能下降或配置被忽略。
为什么小文件不适合用 tcp_nopush + sendfile
tcp_nopush 的设计目标是“合并响应头 + 文件开头数据”进一个 TCP 报文段,前提是:数据能由内核连续供给、且大小接近 MSS(通常约 1448 字节有效载荷)。但小文件存在几个硬性冲突:
- 多数小文件(
- 小文件请求高频并发时,Nginx 更依赖 open_file_cache、内存缓存、HTTP/2 多路复用等机制,而非 TCP 层包合并
- 若小文件路径启用了 gzip(常见于 JS/CSS)、ETag 计算、或由后端动态生成(无 Content-Length),sendfile 自动失效 → tcp_nopush 彻底不生效
真正适合 tcp_nopush + sendfile 的场景
该组合专为单次传输体积较大、内容稳定、路径直连磁盘的资源设计:
- 高清图片(JPG/PNG/WEBP ≥ 100 KB)
- 视频切片(MP4/WEBM/HLS .ts 文件)
- 软件安装包(ZIP/TAR.GZ/ISO)
- 字体文件(WOFF2 ≥ 50 KB)
这些资源满足三个刚性前提:sendfile on、真实磁盘文件(非 proxy_pass 或 FastCGI)、响应头含明确 Content-Length。
针对海量小文件,应优先做这些事
与其强行套用 tcp_nopush,不如聚焦更有效的优化路径:
-
关闭 access_log:在小文件 location 中加
access_log off;,避免日志 I/O 成为高并发瓶颈 -
启用并调优 open_file_cache:
open_file_cache max=20000 inactive=60s;<br>open_file_cache_valid 120s;<br>open_file_cache_min_uses 3;
缓存文件句柄与元数据,大幅减少 stat()/open() 系统调用 - 使用 HTTP/2 或 HTTP/3:多路复用天然解决小文件串行请求延迟,比 TCP 层调优收益更高
- 合理设置 expires 和 Cache-Control:让浏览器和中间 CDN 长期缓存,直接避开回源
- 合并小资源(谨慎):如雪碧图(CSS Sprite)、内联关键 CSS/JS,但需权衡缓存粒度与维护成本
如果仍想在部分小文件上试用,必须严格守规矩
仅当满足全部条件时,才可在特定 location 中启用,例如服务一组 50–200 KB 的 PNG 图标:
- location 必须精确匹配后缀:
location ~* \.(png|jpg|webp)$ - 显式关闭压缩:
gzip off; - 确保 root/alias 指向本地磁盘,且文件存在、权限可读
- 检查响应头是否含
Content-Length(可用 curl -I 验证) - 配套设置:
sendfile on; tcp_nopush on; tcp_nodelay off;
不满足任一条件,Nginx 日志会警告 “tcp_nopush is ignored”,配置即失效。

















