要让 slice 模块在 CDN 边缘节点真正扛住超大文件并发访问,关键在于分片拉取、独立缓存、按需组装三者严丝合缝;必须满足 nginx 启用 http_slice_module、仅 location 块配置、搭配 proxy_pass、源站支持 Accept-Ranges 和 Range、客户端带 Range 头、proxy_buffering on 六大前提,缺一不可。

要让 slice 模块在 CDN 边缘节点真正扛住超大文件(如 2GB 视频、50GB 安装包)的并发访问,关键不是“开了 slice 就行”,而是把分片拉取、独立缓存、按需组装三者严丝合缝地串起来。它本质是用“小请求换带宽平稳、用分片缓存换复用率、用 Range 协同换失败可控”。
必须满足的硬性前提条件
缺一不可,否则 slice 完全不触发:
- nginx 编译时已启用 --with-http_slice_module(主流发行版通常默认开启,执行
nginx -V 2>&1 | grep http_slice可确认) - 配置只能写在 location 块内,http 或 server 级别无效
- 必须搭配 proxy_pass 使用;root/alias 静态服务不走 slice 流程
- 后端源站必须返回 Accept-Ranges: bytes,并能正确响应
Range: bytes=x-y请求(标准 Web 服务器、OSS、S3、兼容 RFC 7233 的 API 均支持) - 客户端请求必须自带 Range 头(如下载器、播放器发起的断点续传或拖拽请求),普通 GET 不激活切片
- 不能与 proxy_buffering off 共存——关闭缓冲会直接禁用 slice 功能
核心配置三要素(少一个就失效)
只写 slice 1m 是没用的。以下三项必须同时存在:
-
传递分片范围:用
proxy_set_header Range $slice_range;,确保每个子请求精准携带类似bytes=0-1048575的头 -
区分缓存键:用
proxy_cache_key "$scheme$host$uri$is_args$args$slice_range";,保证每一片独立缓存,避免不同分片覆盖同一 cache key -
启用 HTTP/1.1 协议栈:加
proxy_http_version 1.1;和proxy_set_header Connection "";,因为 Range 是 HTTP/1.1 特性,且需清除 Connection 头防连接复用干扰
缓存策略必须适配分片逻辑
没有缓存,slice 反而增加延迟和回源压力——每次请求都触发多轮回源,带宽不降反升:
- 缓存路径需启用 slices 参数:
proxy_cache_path /data/cache slices levels=1:2 keys_zone=slice_cache:100m max_size=10g inactive=3d use_temp_path=off; - 缓存状态码必须同时覆盖 200 和 206:
proxy_cache_valid 200 206 1h;(200 表示整文件回源,206 表示分片成功) - 启用 cache_lock 防雪崩:
proxy_cache_lock on; proxy_cache_lock_timeout 3s;,确保相同分片的并发请求只放行第一个穿透后端,其余等待缓存就绪 - 务必禁用 proxy_buffering?错——必须保持
proxy_buffering on(默认值),关闭它会导致 slice 失效
实际效果与典型场景表现
配置到位后,行为变化很直观:
- 用户拖动视频到第 80MB,Nginx 只拉取对应的一两个 slice(如
bytes=81920000-82968575),不加载整 2GB 文件 - 多个用户同时请求不同区间,Nginx 各自拉各自需要的 slice,未被请求的部分完全不回源
- 某一分片回源失败(如网络抖动),仅重传该片,不影响其他分片或整体响应
- 边缘节点首次缓存完成后,后续相同区间请求直接从本地磁盘读 slice,毫秒级响应










