Nginx代理缓存Byte Range功能失效问题求助
Nginx代理缓存后Byte Range功能失效的解决方案
问题背景
我们的后端Web服务器版本老旧,不支持Byte Range下载,因此使用Nginx作为媒体下载URL的代理并启用缓存。但遇到异常:对www.my.com的请求发送Range头后,Nginx总是返回完整文件(HTTP 200),而测试IBM镜像时相同配置却能正常返回206 Partial Content。
当前Nginx配置:
proxy_cache_path /tmp/cache keys_zone=IMAGE:10m inactive=24h; ... location /api/v2/image_proxy/blobs/ { proxy_set_header X-NginX-Proxy true; proxy_set_header Host www.my.com; proxy_buffering on; proxy_cache IMAGE; proxy_cache_valid 200 1d; proxy_ssl_server_name on; proxy_force_ranges on; proxy_ignore_headers Expires; proxy_ignore_headers X-Accel-Expires; proxy_ignore_headers Cache-Control; proxy_ignore_headers Set-Cookie; proxy_hide_header X-Accel-Expires; proxy_hide_header Expires; proxy_hide_header Cache-Control; proxy_hide_header Pragma; proxy_pass https://www.my.com/api/v2/image_proxy/blobs/; }
测试差异:
www.my.com请求:返回HTTP 200 OK,响应头带Transfer-Encoding: chunked(无Content-Length),最终返回完整文件- IBM镜像请求:返回HTTP 206 Partial Content,响应头带
Content-Length和Content-Range,仅返回请求的字节范围内容
问题根源
Nginx的proxy_force_ranges on功能依赖缓存文件的完整大小信息才能处理Range请求:
- IBM镜像的源站返回了明确的
Content-Length头,Nginx缓存文件后可直接获取总大小,因此能正常解析Range请求并返回部分内容。 www.my.com的源站返回Transfer-Encoding: chunked编码的响应,无Content-Length头,Nginx缓存后无法确定文件总长度,导致无法处理Range请求,只能返回完整文件。
解决方案
通过调整配置,确保缓存文件能被正确识别大小,让proxy_force_ranges生效:
调整后的配置
proxy_cache_path /tmp/cache keys_zone=IMAGE:10m inactive=24h; ... location /api/v2/image_proxy/blobs/ { proxy_set_header X-NginX-Proxy true; proxy_set_header Host www.my.com; # 启用HTTP/1.1并重置Connection头,避免chunked编码相关问题 proxy_http_version 1.1; proxy_set_header Connection ""; proxy_buffering on; proxy_cache IMAGE; # 启用缓存锁,确保只有一个请求去后端拉取文件,避免缓存不完整 proxy_cache_lock on; proxy_cache_valid 200 1d; proxy_ssl_server_name on; proxy_force_ranges on; # 禁用请求压缩,避免后端返回chunked编码的压缩内容 proxy_set_header Accept-Encoding ""; proxy_ignore_headers Expires; proxy_ignore_headers X-Accel-Expires; proxy_ignore_headers Cache-Control; proxy_ignore_headers Set-Cookie; proxy_hide_header X-Accel-Expires; proxy_hide_header Expires; proxy_hide_header Cache-Control; proxy_hide_header Pragma; proxy_pass https://www.my.com/api/v2/image_proxy/blobs/; }
验证步骤
- 清理现有缓存:
rm -rf /tmp/cache/* - 重新发起Range请求测试:
curl --range 1000-1099 -v -O "http://localhost:8088/api/v2/image_proxy/blobs/eyJf...150/mini_magick20211102-21-1u44964"
- 检查响应是否返回
HTTP/1.1 206 Partial Content,并包含Content-Range头。
补充说明
Byte Range支持是苹果设备播放媒体的必要条件,修复后可解决苹果设备无法正常播放媒体的问题。
内容的提问来源于stack exchange,提问作者reachlin
相关产品推荐
相关产品推荐

