静态资源大文件下载需分离处理:200全量请求走缓存,206分片请求绕过缓存直出或回源;静态直出依赖原生range模块,代理场景须透传Range头、定制cache_key并禁用206缓存。

静态资源大文件下载要同时支持断点续传和缓存分片,核心不是“让缓存适配分片”,而是把两类请求分开处理:全量请求(200)走缓存,分片请求(206)绕过缓存、直通后端或零拷贝直出。Nginx 默认不缓存 206 响应,但若配置不当,反而会破坏断点逻辑。
静态直出场景:禁用 proxy_cache,靠原生 range 模块 + 浏览器缓存
当 Nginx 直接服务磁盘文件(root 或 alias),它不走代理缓存路径,而是由 ngx_http_range_module 原生处理 Range 请求,天然返回 206 响应。此时关键在避免干扰:
- 删掉
max_ranges 0;,保持默认或设为max_ranges 10; - 对 ZIP/MP4/ISO 等二进制文件,加
gzip_disable "range";,防止压缩扰乱 Content-Range 计算 - 启用
sendfile on;提升吞吐,但若实测与 Range 冲突(如某些内核组合),可临时改sendfile off; - 浏览器缓存用强策略:
add_header Cache-Control "public, max-age=31536000, immutable";,配合版本化 URL(如/dl/app-v3.2.0.zip)避免缓存失效问题
反向代理场景:必须透传 Range 头 + 定制 cache_key + 显式绕过缓存
若文件来自后端服务或对象存储(如 MinIO、S3),Nginx 需作为代理转发。这时默认不传 Range 和 If-Range 头,必须显式补全:
proxy_set_header Range $http_range;proxy_set_header If-Range $http_if_range;proxy_pass_request_headers on;
缓存键必须区分不同分片,否则所有 Range 请求都命中同一缓存条目:
- 正确写法:
proxy_cache_key "$uri|$http_range";(空 Range 时自动为/file.zip|,与分片请求自然隔离) - 只缓存完整响应:
proxy_cache_valid 200 7d; - 禁止缓存分片响应:
proxy_cache_valid 206 0s;或更稳妥地加proxy_cache_bypass $http_range;和proxy_no_cache $http_range;
需要 slice 分片回源时:仅限代理模式,且必须配套缓存与头透传
当后端是远端源站,单次拉取慢、带宽压力大,可用 slice 在代理层拆请求并发回源。但注意:slice 不适用于静态直出,只用于 proxy_pass 场景:
- 确认 Nginx ≥ 1.9.8 且含
ngx_http_slice_module(nginx -V | grep slice) - 在 location 中启用:
slice 2m;(建议 1–5MB,平衡并发与开销) - 透传分片范围:
proxy_set_header Range $slice_range; - 缓存 key 必须含分片标识:
proxy_cache_key "$uri$is_args$args$slice_range"; - 缓存 206 响应:
proxy_cache_valid 206 24h;(否则分片缓存无意义) - 手动补全响应头:
add_header Accept-Ranges bytes;、add_header Content-Range $sent_http_content_range;
验证是否生效的三步检查法
别依赖 guess,用 curl 实测最可靠:
- 查基础响应:
curl -I https://yoursite.com/big.zip→ 应有Accept-Ranges: bytes和200 OK - 测分片响应:
curl -I -H "Range: bytes=0-1023" https://yoursite.com/big.zip→ 应返回206 Partial Content、Content-Range: bytes 0-1023/12345678 - 验缓存行为:
curl -I -H "Range: bytes=1024-2047" https://yoursite.com/big.zip→ 若命中缓存,X-Cache: HIT应出现;若未命中,应为MISS或无该头


















