在 nginx 中配置断点续传下载服务,核心在于正确解析客户端请求头中的 range 字段,并返回对应的 206 partial content 状态码及 content-range 响应头。具体做法是启用 nginx-http-range-filter-module(nginx 1.7.11+ 默认内置),并通过 open_file_cache 优化大文件读取性能,同时配合 expires 或缓存控制指令避免浏览器重复请求。

如何验证 Range 请求是否生效
要验证断点续传功能是否正常工作,需要构造包含 Range: bytes=0-99 的请求头,并检查服务器是否返回 206 状态码以及正确的 Content-Range 头部。如果返回 200 且内容为完整文件,则说明断点续传未生效或配置有误。

location /downloads/ {
root /var/www/html;
# 启用范围请求支持
# Nginx 1.7.11+ 默认已启用 http_range_filter
# 优化大文件读取,减少系统调用
open_file_cache max=1000 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 设置缓存过期时间,避免重复下载
expires 30d;
add_header Cache-Control "public, immutable";
# 处理 MIME 类型
types { }
default_type application/octet-stream;
}
使用 curl 测试:curl -I -H "Range: bytes=0-99" http://localhost/downloads/largefile.zip
预期结果:状态码 206 Partial Content,响应头包含 Content-Range: bytes 0-99/1048576(假设文件大小为 1MB)。若未指定 Range,则返回 200 OK 和完整内容。
如何处理并发下载与资源竞争
在高并发场景下,多个客户端同时请求同一文件的 Range 部分可能导致 I/O 瓶颈。通过合理配置 open_file_cache 和限制 worker_connections,可以有效缓解资源竞争。此外,确保文件权限正确且文件系统支持高效随机读取是关键。

# nginx.conf 全局配置示例
worker_processes auto;
events {
worker_connections 4096;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server {
listen 80;
server_name example.com;
location /downloads/ {
root /var/www/html;
open_file_cache max=2000 inactive=120s;
open_file_cache_valid 60s;
open_file_cache_min_uses 3;
open_file_cache_errors on;
# 禁用压缩,避免影响二进制文件传输
gzip off;
# 添加必要的 CORS 头(如需跨域)
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
add_header Access-Control-Allow-Headers "Range, Accept-Encoding";
if ($request_method = OPTIONS) {
return 204;
}
}
}
}
该配置通过增加 open_file_cache 的最大条目数和延长非活动时间,提升高并发下的文件句柄复用率。同时关闭 gzip 防止对 ZIP、MP4 等已压缩格式进行二次压缩导致错误。CORS 头允许前端 JS 发起 Range 请求,满足现代 Web 应用需求。
当 Range 请求超出文件大小时会返回什么
当客户端请求的 Range 字节范围超出实际文件大小,例如请求 bytes=1000-2000 而文件仅 500 字节,Nginx 将返回 416 Requested Range Not Satisfiable 状态码,并在响应头中包含 Content-Range: bytes */500 表示有效范围。这是 HTTP/1.1 标准行为,无需额外配置即可触发。











