Nginx slice模块用于大文件分片代理,非请求转发;需满足编译支持、后端Range响应、仅location生效三前提,通过slice指令拆分Range子请求并独立缓存分片,降低回源压力、提升并发下载与缓存复用率。

nginx slice模块不是用来“转发请求”的,而是让Nginx在反向代理场景中,把一个大文件的完整响应,按固定字节大小自动拆成多个Range子请求发往后端,并分别缓存各分片。它解决的核心问题是:大文件首次被并发Range访问时,避免整文件回源、降低源站压力、提升缓存复用率。
必须满足的三个前提条件
缺一不可,否则配置无效或返回502/416:
-
编译支持:Nginx需带
--with-http_slice_module编译(1.9.8+内置,但Ubuntu/Debian官方包常未启用)。验证命令:nginx -V 2>&1 | grep http_slice_module -
后端支持Range:源站必须正确响应
206 Partial Content,并返回Content-Range头(如bytes 0-1048575/5242880)。静态服务(Nginx/Apache)、OSS、S3、CDN源站通常支持;动态接口(PHP/Node.js未显式处理Range)则不适用。 -
仅限location块生效:slice指令只能写在
location里,http/server块中设置会被忽略。
关键配置项与作用解析
以下是最小可行配置(以1MB切片为例),每行都影响行为逻辑:
-
slice 1m;:设定单片最大1MB。Nginx根据后端返回的Content-Range自动计算总片数(如5MB文件会发5个子请求)。 -
proxy_set_header Range $slice_range;:将自动生成的bytes=0-1048575等值注入请求头,这是触发后端分片响应的关键。 -
proxy_cache_key "$uri$is_args$args$slice_range";:确保不同分片存为独立缓存项。漏掉$slice_range会导致所有片覆盖同一缓存,失去分片意义。 -
proxy_cache_valid 200 206 1h;:必须同时声明200(整文件)和206(分片)状态码的有效期。否则206响应不会被缓存。 -
proxy_http_version 1.1;:Range是HTTP/1.1特性,不设此值可能导致连接异常或降级为HTTP/1.0全量响应。
真实请求流程与客户端配合方式
客户端行为决定slice是否真正激活:
- 普通GET(无Range头):Nginx仍会按slice大小发起多个子请求回源,但对外返回完整响应(状态码200),适合预热缓存。
- 带Range的请求(如
Range: bytes=0-1048575):Nginx识别后,直接用对应分片响应(206),命中已缓存的那片,不触发新回源。 - 断点续传/多线程下载器(如wget -c、aria2):自动发送多个Range请求,Nginx按需返回对应分片,各片可并行缓存、独立失效。
- 注意:Nginx不合并响应体,也不保证子请求顺序。客户端需自行按字节范围拼接,这与标准HTTP Range语义一致。
调优与避坑要点
常见问题基本源于配置细节或环境限制:
- 切片过小(如128k):50MB文件会触发近400次子请求,易耗尽文件描述符或拖慢首字节时间。建议512k–2M起步,千兆带宽下可试4M。
-
proxy_buffering off冲突:slice模块与该指令互斥,启用会直接报错。如需关闭缓冲,应改用
proxy_buffer_size精细控制。 -
缓存未生效:检查
proxy_cache_bypass是否误判、proxy_cache_lock on是否缺失(防并发穿透)、磁盘空间及权限是否正常。 -
后端返回200而非206:说明源站未识别Range头,检查其是否开启
Accept-Ranges: bytes响应头,或是否对HEAD/GET做了特殊处理。


















