tcp_nopush与tcp_nodelay是协同策略而非互斥开关:前者需配合sendfile用于静态资源合并发送,后者保障动态接口低延迟;二者按场景分路径精细化配置效果最佳。

tcp_nopush 和 tcp_nodelay 不是“开或关”的简单选择,而是针对不同数据特征与传输目标的协同策略。它们不冲突,也不互斥,关键在于理解各自生效条件和作用边界。
静态资源服务(图片/JS/CSS/字体等)
这是 tcp_nopush 最典型的适用场景。前提是必须开启 sendfile,否则 tcp_nopush 完全无效。
- 务必配置:sendfile on; tcp_nopush on;
- tcp_nodelay 可保持默认(on),无需关闭 —— 它会在最后未填满的数据包上起效,避免因等待而卡住响应尾部
- 效果:大文件通过零拷贝高效发出,头部、ETag、Last-Modified 等小字段与主体合并发送,减少 TCP 包数量和往返次数
动态接口与反向代理(API/后端转发/微服务网关)
这类流量不走 sendfile 路径(内容由 upstream 生成,非磁盘文件),因此 tcp_nopush 始终不生效。
- 只需关注:tcp_nodelay on;(默认即如此,通常不用显式写)
- 确保 keepalive 连接开启(proxy_http_version 1.1; proxy_set_header Connection ''),让 tcp_nodelay 在长连接中持续生效
- 特别适合 WebSocket、SSE、实时监控、登录鉴权等对首字节延迟敏感的场景
混合型站点(前端静态 + 后端 API 共存)
推荐按 location 拆分配置,精细化控制:
- 静态资源路径(如 /static/, /assets/, /.well-known/):启用 sendfile + tcp_nopush
- API 路径(如 /api/, /graphql):禁用 sendfile,依赖 tcp_nodelay 保障低延迟
- 示例片段:location /static/ { sendfile on; tcp_nopush on; tcp_nodelay on; }
- 注意:tcp_nodelay 放在 listen 指令中更稳妥(如 listen 443 ssl http2 tcp_nodelay;),它对所有该端口上的连接都生效
高吞吐流媒体或大文件下载(如视频点播、ISO 分发)
需兼顾带宽压榨与连接稳定性,此时需实测验证:
- 仍建议保留 sendfile on; tcp_nopush on; —— 这是提升吞吐的核心
- tcp_nodelay 默认 on 即可;仅当网络极稳定(如内网千兆直连)、且实测发现大量微小 ACK 干扰吞吐时,才谨慎尝试 tcp_nodelay off;
- 务必配合 keepalive_timeout 和 tcp_keepalive 调优,防止连接空闲中断
- 切勿仅凭理论调优:用 wrk 或 curl -w 配合 tcpdump 抓包,观察 PUSH 标志出现频率与包间隔











