nginx高效传输静态资源依赖浏览器缓存、内核零拷贝、文件系统与连接复用三层协同:需精准设置cache-control响应头、成套启用sendfile/tcp_nopush/tcp_nodelay、配置open_file_cache/keepalive/read_ahead,并按资源类型差异化启用gzip_static或sendfile_max_chunk。

浏览器端精准控制缓存行为
用户重复访问时,不该再走网络——关键在响应头是否“说清楚”:
- 带哈希的 JS/CSS/字体(如
app.8f3a2d.js):用Cache-Control: public, max-age=31536000, immutable,浏览器永久信任该 URL,不发验证请求 - 普通图片、图标等无哈希资源:设
max-age=604800(7 天),避免更新后用户卡旧版 - HTML 页面本身:设
no-cache或max-age=60,确保每次打开都能检查新版本
内核级零拷贝路径必须成套启用
高效发送不是“开了 sendfile 就行”,而是一整套内核协作机制:
-
sendfile on;:启用内核直传,跳过用户态缓冲 -
tcp_nopush on;:配合 sendfile,把响应头和文件体合并成满包发出,减少小包数量 -
tcp_nodelay off;:显式关闭 Nagle 算法,防止它干扰 tcp_nopush 的攒包逻辑
只要出现以下任一情况,Nginx 就会自动退化回传统 read()+write() 模式(四次拷贝+四次上下文切换):
– 启用了 gzip on 或 gunzip on
– 配置了 proxy_pass、sub_filter 或 add_before_body
– 文件放在 NFS、FUSE 或某些容器存储挂载点上
– 响应缺少 Content-Length(如 chunked 编码)
文件系统与连接层收敛高频开销
高并发下,频繁打开文件、记录日志、建立连接都会成为瓶颈:
-
open_file_cache max=10000 inactive=60s;:缓存文件句柄和元信息(存在性、大小、修改时间),大幅减少open()和stat()系统调用 -
access_log off;:在纯静态资源 location 中彻底关闭访问日志;若需记录,避免使用$body_bytes_sent类需等待响应完成的变量 -
keepalive_timeout 65; keepalive_requests 1000;:延长 TCP 连接空闲时间,允许单连接处理上千请求,尤其利于加载含大量资源的页面 -
read_ahead 1m;:对 ≥4MB 的文件(如高清图、短视频),提示内核预加载页缓存,SSD 上效果明显
按资源类型差异化配置更稳
一刀切的全局设置容易误伤性能:
- JS/CSS/HTML 等文本资源:启用
gzip_static on;+gzip off;,用预压缩的.gz文件,既压缩又不破坏零拷贝 - PNG/JPG/WebP/SVG 等二进制资源:关闭 gzip,但必须开启
sendfile和tcp_nopush - MP4/ZIP 等大文件:加
sendfile_max_chunk 512k;,防止单次传输阻塞事件循环 - Favicon/robots.txt 这类 ≤1KB 资源:可单独设
tcp_nodelay on;,末尾数据立即发出,延迟下降明显











