
用户反馈“下载文件到一半就断了”,自己用wget或curl测试,果然看到屏幕上反复出现 HTTP 206 Partial Content,文件下了又断、断了又重试,折腾半天也拿不到完整文件。
很多人第一反应是“客户端网络有问题”“用户操作不当”,但其实,这锅多半要Nginx代理来背。
今天就从「现象→原因→排查→解决」,一步步拆解这个高频问题,帮你彻底根治,再也不用被用户催更、被领导追问!
一、先看现象:你是不是也遇到过这种情况?
先给大家复现一下最常见的场景,对号入座:
wget -c http://xxxx.com/bigfile.js
用wget下载大文件(比如几百M、1G以上的安装包、压缩包),命令如下:


总结几个核心现象,一眼识别问题:
执行后,日志会反复出现这样的内容:
客户端反复重试,日志固定出现「206 Partial Content」
文件永远下载不完整,每次只下载一部分就中断
小文件(几十M以内)下载无异常,大文件必断
本地直接访问上游服务器(跳过Nginx),下载完全正常
二、深度剖析:4个核心原因,击溃Nginx大文件下载
当Nginx作为反向代理时,会充当“中间人”——接收客户端请求,转发给上游服务器,再把上游的响应缓存、处理后,发送给客户端。
大文件下载中断,本质就是这个“中间人”的「缓冲、超时、传输机制」出了问题,具体有4点:
1. 代理缓冲不足(最常见!)
重点提醒:206状态码本身不是错误,它是HTTP的“断点续传”机制,之所以反复出现,是因为Nginx提前断开了连接,客户端只能反复发起续传请求。
proxy_buffer_size 4k; # 单个缓冲区大小,默认4k
proxy_buffers 4 32k; # 缓冲区数量+单个大小,默认4个32k
proxy_busy_buffers_size 64k; # 忙碌时可使用的最大缓冲区,默认64k
当文件较大(比如超过100M),缓冲区很快就会被占满;如果服务器I/O较慢,临时文件写入跟不上,Nginx就会直接断开连接,避免占用过多资源——这是它的“自我保护”,却坑了我们的下载功能。
更坑的是,若临时文件缓存上限不足(proxy_max_temp_file_size默认值较小),外网下载速度慢时,Nginx会因无法缓存全部内容而中断连接,这也是很多人“内网下载正常、外网必断”的核心原因。
2. 超时限制太短(隐形杀手)
Nginx默认会把上游服务器的响应,先缓存到内存或临时文件中,再逐步发送给客户端。但它的默认缓冲区配置,对大文件极其不友好:
举个例子:1G的文件,客户端下载速度只有100KB/s,下载完需要近3小时,而Nginx默认60秒没传输完就断连,自然会反复中断。
3. 206断点续传的“误判”
Nginx对代理连接有3个关键超时参数,默认都是60秒——这个时间对大文件下载来说,太短了!
客户端下载中断后,会自动发起「Range请求」(比如“从第300K字节开始下载”),服务器返回206状态码,代表“仅返回部分内容”——这是正常的断点续传逻辑。
但问题的核心是:客户端之所以需要续传,是因为Nginx提前关闭了连接,而非客户端主动中断。206只是“结果”,不是“原因”。
4. sendfile/tcp_nopush的“副作用”
很多人看到206就以为是客户端的问题,其实搞反了:
但这个优化有个副作用:当客户端下载速度慢、或Nginx缓冲不足时,TCP连接会因“数据发送不及时”被中途断开,尤其是文件超过1G时,这个问题会更明显。
补充:若Nginx未开启TCP长连接(keepalive),也会导致连接频繁断开,加重下载中断问题。
Nginx有个优化大文件传输的功能:sendfile(直接从内核发送文件,跳过用户空间,提升速度),通常会和tcp_nopush配合开启。
遇到问题不用慌,按这3步排查,快速锁定原因,避免瞎改配置:
1. 查看Nginx日志(最直接)
三、3步排查:快速定位问题,不瞎折腾
tail -f /var/log/nginx/access.log # 访问日志,看状态码
tail -f /var/log/nginx/error.log # 错误日志,看具体报错
重点关注这几个状态码/报错:
通过日志查看连接断开的具体原因,执行命令:
502/504:上游连接超时或失败(检查上游服务器)
499:客户端主动关闭连接(较少见,可能是用户中途取消)
2. 测试不同下载方式
104: Connection reset by peer:上游服务器因等待过久,主动断开连接(多为缓冲区不足导致)
curl -O -C - http://example.com/bigfile.js
如果分段下载能成功,但无法一次性下载完成,说明问题一定在Nginx代理或服务器端,和客户端无关。
用curl测试断点续传,看是否能正常续传:
直接访问上游服务器IP(跳过Nginx),测试下载:若正常,确定是Nginx配置问题;若仍断开,检查上游服务器。
排除CDN、防火墙干扰:临时关闭CDN或防火墙,再测试下载,排除外部拦截。
3. 排除网络/上游干扰
找到原因后,针对性调整Nginx配置即可,以下是通用解决方案,直接复制到你的location或server块中,根据实际情况微调即可。
1. 核心配置(必改)
四、终极解决方案:复制即用,彻底根治
location / {
proxy_pass http://upstream_server; # 替换成你的上游服务器地址
# 缓冲区配置(重点优化,根据文件大小调整)
proxy_buffering on; # 开启代理缓冲
proxy_buffer_size 128k; # 单个缓冲区增大到128k
proxy_buffers 4 256k; # 4个缓冲区,每个256k
proxy_busy_buffers_size 256k; # 忙碌时最大缓冲区256k
proxy_temp_file_write_size 20M; # 临时文件写入缓冲,避免I/O卡顿
proxy_max_temp_file_size 10240M; # 临时文件最大上限,适配10G内大文件
# 超时配置(延长至5分钟/300秒,可根据文件大小调整)
proxy_read_timeout 300s; # 等待上游响应超时
proxy_send_timeout 300s; # 向客户端发送数据超时
proxy_connect_timeout 60s; # 连接上游超时(无需过长)
# 支持断点续传(必加,避免206反复出现)
proxy_http_version 1.1; # 启用HTTP/1.1,支持长连接
proxy_set_header Connection ""; # 清空Connection头,避免连接复用干扰
proxy_socket_keepalive on; # 开启TCP长连接,减少断开频率
}
2. 进阶优化:大文件内部直发(可选)
调整缓冲区、超时时间,保留断点续传支持,解决90%的问题:
使用 X-Accel-Redirect 指令,让上游服务器返回该头信息,指定文件路径,Nginx会直接直发文件,无需经过代理缓冲。
补充:若需进一步优化大文件传输,可启用Nginx的slice模块,实现分片代理,降低上游服务器压力,需确保Nginx编译时开启了--with-http_slice_module(主流发行版默认开启),配置示例如下:
location /download/ {
slice 1m; # 每片1MB,视频类可设为4-10m
proxy_cache cache_one; # 启用缓存,缓存分片内容
proxy_cache_valid 200 206 1h; # 缓存200、206状态码,有效期1小时
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Range $slice_range; # 自动注入分片Range请求头
proxy_pass http://backend$uri$is_args$args; # 替换为你的上游地址
}
3. 配置生效与测试
修改配置后,一定要先检查配置是否正确,再重启Nginx:
nginx -t # 检查配置语法(关键!避免配置错误导致Nginx无法启动)
nginx -s reload # 平滑重启Nginx,不中断现有服务
重启后,用curl或wget测试:
curl -O -C - http://example.com/bigfile.js
正常情况下,文件会一次性下载完成,不再出现206重试、连接断开的情况。
如果是静态大文件(如安装包、视频),可以让Nginx直接读取本地文件,跳过上游代理,避免缓冲和临时文件写入,效率更高:
五、总结:
Nginx 代理下载大文件出现中断,是 代理缓冲、超时限制 + sendfile/tcp_nopush 组合的副作用 wget/curl 出现 206 Partial Content只是客户端断点续传的表现调整缓冲区、超时、支持 Range 就能解决问题
原理:Nginx 默认“保护服务器和缓冲资源”,导致长连接大文件传输容易被中途关闭。
如果觉得有用,欢迎点赞、在看,转发给身边的运维/开发同学,一起避开Nginx那些让人头大的坑!
夜雨聆风