核心是协同配置tcp_nopush与tcp_nodelay:前者需sendfile on配合,合并大文件整包发送以降小包数量;后者禁用nagle算法,确保末尾不满数据立即发出以保低延迟;二者按路径精细化设置,不可全局统一启用。

Nginx 优化静态资源传输的 TCP 参数,核心不是“调连接池”,而是精准控制内核网络栈的行为:让大文件发得更省(少包)、小资源回得更快(低延迟),两者并不矛盾,关键在协同配置。
明确 tcp_nopush 和 tcp_nodelay 的分工
tcp_nopush 不是“禁用 Nagle”,而是启用 TCP_CORK 机制,让内核把响应头+响应体攒成满包再发,降低小包数量;tcp_nodelay 才是真正禁用 Nagle,确保最后一块不满的数据也立刻发出。它们作用阶段不同——前者管“主体传输”,后者管“末尾兜底”。
必须配套 sendfile 才能生效
tcp_nopush 只在 sendfile on; 开启时起作用,因为只有零拷贝路径下,Nginx 才能把文件直接交由内核调度发送。如果用了 proxy_pass 或需要读取后处理(如 gzip),tcp_nopush 就不参与。所以基础三件套是:
sendfile on;tcp_nopush on;tcp_nodelay on;
按资源类型分路径精细化设置
全局开启容易误伤,推荐在 server 或具体 location 块中配置:
- 对 JS、CSS、woff2、webp 等中小体积但首屏关键的资源,同时开
tcp_nopush on; tcp_nodelay on; - 对 >1MB 的图片或视频,可关
tcp_nodelay(即tcp_nodelay off;),专注吞吐,避免频繁小包干扰 - 对 favicon.ico、robots.txt 这类 ≤1KB 的极小资源,
tcp_nodelay on效果最明显,延迟可降 100–200ms
配合缓冲与长度明确性
要让 tcp_nopush 真正攒包,Nginx 必须知道响应体总长:
- 静态服务(
root+try_files)天然满足Content-Length,直接生效 - 若走反向代理(如拉取对象存储),需确保后端返回
Content-Length(非 chunked),且proxy_buffering on;缓存完整响应
验证是否起效的实操方法
不用猜,用工具看:
-
tcpdump -i any port 80 -w nginx.pcap抓包,对比同一 CSS 文件开启/关闭tcp_nopush时的 TCP 包数量和大小 -
ss -i state established '( dport = :80 )'查看连接的retrans(重传)和unacked(未确认字节),数值明显下降说明传输更稳
不复杂但容易忽略。











