首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >多线程下载为什么快?聊聊 HTTP 的 Range 请求

多线程下载为什么快?聊聊 HTTP 的 Range 请求

原创
作者头像
PC电脑医生
修改于 2026-10-10 15:38:30
修改于 2026-10-10 15:38:30
1500
举报

同一个文件,用浏览器下和用 Motrix 下,速度经常差好几倍。

原因通常被归结为"下载器开了多线程"。

但"多线程"这个说法其实不准确——它并不是把一条通道加宽,而是同时开了好几条通道。

这个能力来自 HTTP 协议里的一个字段。搞懂了它,也就知道 Motrix 里那几个参数到底在调什么。

普通下载只有一条路

浏览器下载文件时,过程很直接:

代码语言:bash
复制
请求整个文件 → 服务器返回整个文件 → 存到本地

从头到尾只有一条 TCP 连接。

这条连接的速度,受几个因素限制:

  • 服务器给了多少带宽
  • 你到服务器之间的网络质量
  • 单条连接的传输效率——这是关键

TCP 有个特点:数据传输速率会受"往返时间"和"丢包"影响。

距离远、链路差的服务器上,单条连接经常跑不满你的带宽——不是没带宽,是这条道跑不快。

Range 请求:只要文件的一部分

HTTP 协议提供了一个字段,可以让客户端只请求文件的一部分:

代码语言:bash
复制
Range: bytes=0-1023

这一行的意思是:只要前 1024 字节(0 到 1023)。

服务器如果支持,会返回一个特殊的状态码 206 Partial Content——表示"这是部分内容",而不是完整的文件。

响应头里还会带上:

  • Content-Range:这段内容在原文件中的位置
  • Content-Length:这段内容的长度

这就是"分段下载"的基础。

切成几段,同时下

有了 Range,多线程下载就顺理成章了:

第一步:先问清楚文件多大

发一个 HEAD 请求,拿到 Content-Length——文件总大小。

同时确认响应头里有没有这个:

代码语言:bash
复制
Accept-Ranges: bytes

这一行表示服务器支持 Range 请求。 没有它,后面的步骤都做不了。

第二步:分块

把文件按大小切成 N 段。比如 4 段:

  • 1:bytes=0-262143
  • 2:bytes=262144-524287
  • 3:bytes=524288-786431
  • 4:bytes=786432-

第三步:并发请求

四个线程同时发起请求,各自下载自己的那一段。

这就是"多线程"的真相——不是一条道跑得更快,而是同时开了四条道。

第四步:本地合并

数据写入同一个文件的对应偏移位置,全部完成后就是一个完整文件。

断点续传是同一套机制

断点续传,其实就是 Range 的另一个用法。

下载中断时,客户端记录每个分块已经下到哪了。

这个记录通常存在一个临时文件里(比如 .part 文件或者一个 .json 记录)。

恢复下载时,从记录的位置继续请求:

代码语言:bash
复制
Range: bytes=1048576-

注意末尾没有写结束位置——意思是"从 1048576 字节一直下到文件结束"。

服务器把这之后的数据传回来,客户端接到已下载部分的末尾。

所以断点续传能工作,前提也是服务器支持 Range。

不是所有服务器都支持

这是实际使用中会遇到的限制。

如果服务器不支持 Range,你发带 Range 头的请求,它会:

  • 返回 200 OK(而不是 206)
  • 直接给你整个文件

看状态码就能判断:206 是支持,200 是不支持。

这种情况下,多线程和续传都没法用——只能老老实实单线程下完。

某些网盘的直链、动态生成的文件就属于这类。下载器对着它们也没办法,这不是软件的问题。

分段越多就越快吗

直觉上,切成 16 段应该比 4 段快得多。

实际不是这样,有几个制约。

请求本身有开销

每一段都要单独建立连接、发送请求头、等待响应。

段切得太碎,这些开销占比就上去了。 小文件切很多段,反而更慢。

服务器会限制并发

很多服务器对单个 IP 的并发连接数有限制。

你开 16 个连接,可能有一半被拒绝或排队。更糟的是,有些服务器会判定为异常请求,直接限速甚至封 IP。

客户端自己也有瓶颈

下载速度快到一定程度,磁盘写入可能成为新瓶颈——尤其是机械硬盘。

另外线程太多,CPU 调度和内存占用的开销也会上升。

常见的做法:动态分配

更合理的策略不是"平均切 N 份",而是抢占式:

  • 文件切成很多小块,放进队列
  • 每个线程完成一块,就从队列领下一块
  • 直到队列清空

好处是:某个线程遇到慢的块,其他线程不会跟着等。 整体效率比平均分配高。

这些和下载器的设置对得上

理解了机制,再看下载器里的参数,就知道它们在调什么了。

以 Motrix 为例(它底层跑的是 aria2):

  • split:切成几段——单个文件的并行段数
  • max-connection-per-server:单服务器最大并发连接数
  • min-split-size:小于这个大小就不切——避免小文件被切碎

所以那几个参数不是玄学:

  • split 调大 → 段数多,但受限于服务器并发上限
  • min-split-size 调小 → 更多文件能享受多线程,但开销也上去了

调参的本质,是在"并行带来的收益"和"并发带来的开销"之间找平衡点。

一个实际推论

知道了原理,有些现象就能解释了。

为什么下同一个文件,有时快有时慢?

除了网络波动,还要看服务器当前的并发策略。有些服务器在高峰期会收紧单 IP 连接数,Motrix 这边只能被动接受。

为什么有的文件快到飞起,有的慢如蜗牛?

如果那个文件所在的服务器不支持 Range,Motrix 只能单线程跑——再好的参数配置也用不上。

为什么续传有时不灵?

可能是服务器不支持 Range,也可能是下载器还没记录下断点位置就异常退出了。

一句总结

"多线程下载"不是把一条路拓宽,而是同时走了好几条路。

这条路能不能走,取决于服务器认不认 Range 这个请求头;能走几条,取决于服务器允许多少并发。

协议提供的是可能性,实际速度是各方协商的结果。

Motrix 能做的,是在这套规则里把你的参数调到最合适的位置。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 普通下载只有一条路
  • Range 请求:只要文件的一部分
  • 切成几段,同时下
  • 断点续传是同一套机制
  • 不是所有服务器都支持
  • 分段越多就越快吗
    • 请求本身有开销
    • 服务器会限制并发
    • 客户端自己也有瓶颈
    • 常见的做法:动态分配
  • 这些和下载器的设置对得上
  • 一个实际推论
  • 一句总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档