如何通过配置 proxy_set_header Range 实现大文件断点续传的缓存加速优化?
- 内容介绍
- 文章标签
- 相关推荐
本文共计800个文字,预计阅读时间需要4分钟。
要让缓存系统(如+Nginx+)真正支持大文件断点续传并实现加速,关键不只是一行代码proxy_set_header Range $http_range,而是涉及整条链路的识别、传输、响应与缓存协同工作。
以下是核心环节的解析:
确保客户端 Range 请求能完整抵达源站
Nginx 默认在 proxy_pass 场景下不会自动透传 Range 和 If-Range 头,尤其当配置了自定义 proxy_set_header 时,原有请求头可能被覆盖或丢失。必须显式声明:
-
proxy_set_header Range $http_range; -
proxy_set_header If-Range $http_if_range;
这两行需放在location块中proxy_pass之前。若$http_range为空(即客户端没发 Range),Nginx 会传空值或不传该头,不影响正常 200 响应,安全可靠。
让后端服务真正返回 206 响应,而非降级为 200
源站(如另一台 Nginx、OSS、S3 或 PHP 文件服务)必须:
- 支持字节范围读取(例如静态文件服务未禁用
range指令) - 文件可读且未被认证、重写等逻辑拦截(比如
satisfy any+allow/deny可能跳过 range 处理) - 对
Range: bytes=100-199这类请求,返回HTTP/1.1 206 Partial Content+Content-Range: bytes 100-199/1234567
可用 curl 快速验证:curl -I -H "Range: bytes=0-1023" https://your-domain.com/video.mp4
看到
206和Content-Range才算通过。
合理缓存 206 响应,避免重复回源
CDN 或 Nginx 缓存层若把 206 响应全量缓存,但 key 没区分 Range 范围,就会导致“一个分片缓存覆盖全部请求”。正确做法是:
- 使用
$slice_range(配合slice模块)或$http_range构建唯一缓存 key - 示例:
proxy_cache_key "$uri$is_args$args$slice_range"; - 同时启用
proxy_cache_valid 200 206 1h;—— 明确允许缓存 206 -
禁用对 Range 请求的强制缓存策略,比如不要设
Cache-Control: public, max-age=31536000,否则 CDN 可能直接返回旧的 200 全量缓存。
(进阶)用 slice 模块实现智能分片代理
当源站较慢或带宽受限时,slice 是提升并发下载效率的关键:
- 在
location中启用:slice 1m;(每片最大 1MB) -
proxy_set_header Range $slice_range;(Nginx 自动注入当前切片范围) -
proxy_http_version 1.1;(Range 是 HTTP/1.1 特性,必须声明) - 后端必须支持 Range(如标准 Web 服务器、对象存储),否则会返回 416 或完整体
这样,多个用户请求不同区间时,Nginx 可并行拉取不同 slice 并分别缓存,显著降低源站压力。
不复杂但容易忽略
本文共计800个文字,预计阅读时间需要4分钟。
要让缓存系统(如+Nginx+)真正支持大文件断点续传并实现加速,关键不只是一行代码proxy_set_header Range $http_range,而是涉及整条链路的识别、传输、响应与缓存协同工作。
以下是核心环节的解析:
确保客户端 Range 请求能完整抵达源站
Nginx 默认在 proxy_pass 场景下不会自动透传 Range 和 If-Range 头,尤其当配置了自定义 proxy_set_header 时,原有请求头可能被覆盖或丢失。必须显式声明:
-
proxy_set_header Range $http_range; -
proxy_set_header If-Range $http_if_range;
这两行需放在location块中proxy_pass之前。若$http_range为空(即客户端没发 Range),Nginx 会传空值或不传该头,不影响正常 200 响应,安全可靠。
让后端服务真正返回 206 响应,而非降级为 200
源站(如另一台 Nginx、OSS、S3 或 PHP 文件服务)必须:
- 支持字节范围读取(例如静态文件服务未禁用
range指令) - 文件可读且未被认证、重写等逻辑拦截(比如
satisfy any+allow/deny可能跳过 range 处理) - 对
Range: bytes=100-199这类请求,返回HTTP/1.1 206 Partial Content+Content-Range: bytes 100-199/1234567
可用 curl 快速验证:curl -I -H "Range: bytes=0-1023" https://your-domain.com/video.mp4
看到
206和Content-Range才算通过。
合理缓存 206 响应,避免重复回源
CDN 或 Nginx 缓存层若把 206 响应全量缓存,但 key 没区分 Range 范围,就会导致“一个分片缓存覆盖全部请求”。正确做法是:
- 使用
$slice_range(配合slice模块)或$http_range构建唯一缓存 key - 示例:
proxy_cache_key "$uri$is_args$args$slice_range"; - 同时启用
proxy_cache_valid 200 206 1h;—— 明确允许缓存 206 -
禁用对 Range 请求的强制缓存策略,比如不要设
Cache-Control: public, max-age=31536000,否则 CDN 可能直接返回旧的 200 全量缓存。
(进阶)用 slice 模块实现智能分片代理
当源站较慢或带宽受限时,slice 是提升并发下载效率的关键:
- 在
location中启用:slice 1m;(每片最大 1MB) -
proxy_set_header Range $slice_range;(Nginx 自动注入当前切片范围) -
proxy_http_version 1.1;(Range 是 HTTP/1.1 特性,必须声明) - 后端必须支持 Range(如标准 Web 服务器、对象存储),否则会返回 416 或完整体
这样,多个用户请求不同区间时,Nginx 可并行拉取不同 slice 并分别缓存,显著降低源站压力。
不复杂但容易忽略

