开启 sendfile 并配合 tcp_nopush 可显著提升静态文件传输效率,通过内核零拷贝和 TCP 包合并减少系统调用与小包数量;需配置 sendfile on、sendfile_max_chunk 512k、tcp_nopush on,并辅以 access_log off、open_file_cache 及内核参数调优。

开启 sendfile 并配合 tcp_nopush,能显著提升静态文件(如图片、CSS、JS)在高并发场景下的传输效率,减少系统调用和网络小包数量。
启用 sendfile 提升内核级零拷贝
Nginx 默认可能未开启 sendfile,它让内核直接将磁盘文件通过 DMA 送入 socket 缓冲区,跳过用户态内存拷贝,降低 CPU 和上下文切换开销。
在 http 或 server 块中添加:
sendfile_max_chunk 512k;
sendfile_max_chunk 限制单次 sendfile 传输量,避免阻塞事件循环;512k 是较稳妥的值,可根据文件平均大小微调。
tcp_nopush:合并 TCP 包,减少 Nagle 干扰
tcp_nopush 需与 sendfile 协同生效。开启后,Nginx 会在发送完整响应头 + 文件数据前,尽可能把数据塞进一个 TCP 包(受 MSS 限制),避免因 Nagle 算法或延迟 ACK 导致的小包堆积。
配置方式:
tcp_nopush on;注意:该指令仅对使用 sendfile 的响应起作用;若响应启用了压缩(gzip)或动态内容,则不触发。
配套调优建议
-
关闭 access_log 对静态资源:高频小文件读取时,日志写入会成为瓶颈。可用
location匹配后加access_log off; -
设置合理的 open_file_cache:缓存文件句柄和元信息,减少
stat()和open()系统调用
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2; -
确保 kernel 参数适配:如
net.ipv4.tcp_fin_timeout(缩短 TIME_WAIT)、fs.file-max(提高文件描述符上限)等需按实际并发量调整
验证是否生效
用 strace -e trace=sendfile,write,writev -p $(pgrep nginx) 观察 worker 进程是否调用 sendfile;再用 Wireshark 抓包,检查静态资源响应是否集中在 1–2 个 TCP 段内,且无大量


















