nginx高效支持大文件分片下载需启用slice模块并三层协同:请求识别(proxy_set_header range $slice_range)、缓存区分(proxy_cache_key含$slice_range)、响应保真(add_header accept-ranges bytes等)。

要让 Nginx 真正高效支持大文件分片下载(Range 请求),关键不是“缓存整个文件”,而是让每个 Range 请求能被独立识别、正确回源、精准缓存、完整返回。这需要三层协同:请求识别 → 缓存区分 → 响应保真。配置不当,轻则卡顿、seek 失效,重则 416 错误或反复回源。
必须启用 slice 模块并正确使用它
slice 不是“缓存切片”,而是为大文件做分片代理回源的工具——把一个 Range 请求拆成多个子请求发给后端,再合并返回。它本身不缓存,但为缓存提供前提条件。
- 确认模块已编译:
nginx -V 2>&1 | grep http_slice_module,无输出需重编译加--with-http_slice_module -
slice指令只能写在location块内,例如:slice 1m; # 每次向后端请求 1MB 分片
- 同时必须配齐以下三项,缺一不可:
-
proxy_set_header Range $slice_range;(把当前分片范围透传给后端) -
proxy_cache_key "$uri$is_args$args$slice_range";(让每个分片有独立缓存 key) -
proxy_http_version 1.1; proxy_set_header Connection "";(避免 HTTP/1.0 连接干扰)
-
缓存策略必须适配 Range 语义
默认缓存会把所有 Range 请求混为一谈,导致缓存碎片化或命中失败。必须显式控制缓存粒度与生命周期:
- 允许缓存 200 和 206 响应(两者都可能出现):
proxy_cache_valid 200 206 2h; - 开启缓存锁,防并发穿透:
proxy_cache_lock on; - 缩短 inactive 时间,避免冷分片长期占盘:
proxy_cache_path /var/cache/nginx/video levels=1:2 keys_zone=video_cache:128m inactive=10m max_size=5g; - 强制忽略后端错误缓存头(如
Cache-Control: no-cache):proxy_ignore_headers Cache-Control Expires Set-Cookie;
保障响应头完整与传输稳定
很多卡顿源于响应头缺失、截断或缓冲区过小,浏览器无法解析分片边界:
- 显式添加关键头:
add_header Accept-Ranges bytes; - 增大响应头缓冲区(防 Content-Range 被截):
proxy_buffer_size 128k; - 关闭代理缓冲(推荐用于纯流式场景):
proxy_buffering off;
若需 buffering(如鉴权),则调小缓冲:proxy_buffers 4 64k; proxy_busy_buffers_size 64k; - 确保后端返回标准 206 响应,含:
Content-Range: bytes 0-1048575/5242880Accept-Ranges: bytesETag(可选但利于客户端校验)
静态文件托管场景另作处理
如果 Nginx 直接 root 或 alias 提供 MP4/ZIP 等文件,无需 proxy_cache,也不该开 slice:
- 关闭 gzip 对 range 请求的影响:
gzip_disable "range"; - 确保
ngx_http_range_module生效(默认开启) - 不要配置
proxy_cache或slice,否则反而干扰原生 range 处理
不复杂但容易忽略











