
同一个文件,用浏览器下和用 Motrix 下,速度经常差好几倍。
原因通常被归结为"下载器开了多线程"。
但"多线程"这个说法其实不准确——它并不是把一条通道加宽,而是同时开了好几条通道。
这个能力来自 HTTP 协议里的一个字段。搞懂了它,也就知道 Motrix 里那几个参数到底在调什么。
浏览器下载文件时,过程很直接:
请求整个文件 → 服务器返回整个文件 → 存到本地从头到尾只有一条 TCP 连接。
这条连接的速度,受几个因素限制:
TCP 有个特点:数据传输速率会受"往返时间"和"丢包"影响。
距离远、链路差的服务器上,单条连接经常跑不满你的带宽——不是没带宽,是这条道跑不快。
HTTP 协议提供了一个字段,可以让客户端只请求文件的一部分:
Range: bytes=0-1023这一行的意思是:只要前 1024 字节(0 到 1023)。
服务器如果支持,会返回一个特殊的状态码 206 Partial Content——表示"这是部分内容",而不是完整的文件。
响应头里还会带上:
这就是"分段下载"的基础。
有了 Range,多线程下载就顺理成章了:
第一步:先问清楚文件多大
发一个 HEAD 请求,拿到 Content-Length——文件总大小。
同时确认响应头里有没有这个:
Accept-Ranges: bytes这一行表示服务器支持 Range 请求。 没有它,后面的步骤都做不了。
第二步:分块
把文件按大小切成 N 段。比如 4 段:
第三步:并发请求
四个线程同时发起请求,各自下载自己的那一段。
这就是"多线程"的真相——不是一条道跑得更快,而是同时开了四条道。
第四步:本地合并
数据写入同一个文件的对应偏移位置,全部完成后就是一个完整文件。
断点续传,其实就是 Range 的另一个用法。
下载中断时,客户端记录每个分块已经下到哪了。
这个记录通常存在一个临时文件里(比如 .part 文件或者一个 .json 记录)。
恢复下载时,从记录的位置继续请求:
Range: bytes=1048576-注意末尾没有写结束位置——意思是"从 1048576 字节一直下到文件结束"。
服务器把这之后的数据传回来,客户端接到已下载部分的末尾。
所以断点续传能工作,前提也是服务器支持 Range。
这是实际使用中会遇到的限制。
如果服务器不支持 Range,你发带 Range 头的请求,它会:
看状态码就能判断:206 是支持,200 是不支持。
这种情况下,多线程和续传都没法用——只能老老实实单线程下完。
某些网盘的直链、动态生成的文件就属于这类。下载器对着它们也没办法,这不是软件的问题。
直觉上,切成 16 段应该比 4 段快得多。
实际不是这样,有几个制约。
每一段都要单独建立连接、发送请求头、等待响应。
段切得太碎,这些开销占比就上去了。 小文件切很多段,反而更慢。
很多服务器对单个 IP 的并发连接数有限制。
你开 16 个连接,可能有一半被拒绝或排队。更糟的是,有些服务器会判定为异常请求,直接限速甚至封 IP。
下载速度快到一定程度,磁盘写入可能成为新瓶颈——尤其是机械硬盘。
另外线程太多,CPU 调度和内存占用的开销也会上升。
更合理的策略不是"平均切 N 份",而是抢占式:
好处是:某个线程遇到慢的块,其他线程不会跟着等。 整体效率比平均分配高。
理解了机制,再看下载器里的参数,就知道它们在调什么了。
以 Motrix 为例(它底层跑的是 aria2):
所以那几个参数不是玄学:
调参的本质,是在"并行带来的收益"和"并发带来的开销"之间找平衡点。
知道了原理,有些现象就能解释了。
为什么下同一个文件,有时快有时慢?
除了网络波动,还要看服务器当前的并发策略。有些服务器在高峰期会收紧单 IP 连接数,Motrix 这边只能被动接受。
为什么有的文件快到飞起,有的慢如蜗牛?
如果那个文件所在的服务器不支持 Range,Motrix 只能单线程跑——再好的参数配置也用不上。
为什么续传有时不灵?
可能是服务器不支持 Range,也可能是下载器还没记录下断点位置就异常退出了。
"多线程下载"不是把一条路拓宽,而是同时走了好几条路。
这条路能不能走,取决于服务器认不认 Range 这个请求头;能走几条,取决于服务器允许多少并发。
协议提供的是可能性,实际速度是各方协商的结果。
Motrix 能做的,是在这套规则里把你的参数调到最合适的位置。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。