2GB 文件传一半断网实测:HTTP 断点续传只补 15MB

0 阅读8分钟

2GB 的文件传到 78%,网断了。

整文件重传从 0 开始,这一趟一共发了 3.6GB,耗时 190.3 秒。

切成 410 个 5MB 分片再传,只补了 15MB,118 秒传完。

图 1:默认参数下的初始界面,左侧 8 个参数,中间 410 个分片全部待传

在线案例与源码:gitcode.com/OPCTeam/dem… 成品只有一个 index.html,双击就能打开。

一、先看差在哪:一次断网差 1.5GB

两条链路跑的是同一份 2048MB 文件、同一次 78% 断网、同样的 8 秒恢复时间。

网上一搜“断点续传”,大多是贴一段切片代码,很少给失败前后的字节对比。

我把两种传法放进同一个页面,用同一组参数跑了一遍。

指标整文件上传5MB 分片 + 断点续传差值
总线发送量3645.4 MB2063.0 MB少 1582.4 MB
总耗时190.3 s118.0 s少 72.3 s
重传字节1597.4 MB15.0 MB少 1582.4 MB
重传率43.8%0.7%降 43.1 个点
有效吞吐10.8 MB/s17.4 MB/s高 6.6 MB/s

整文件那 1597.4MB 不是白算的。

断网时它已经传到 78%,服务端收没收到、收到多少,浏览器都不知道。

重试只能从第 0 字节再来一遍。

分片模式只丢正在传的那一批。

3 个并发分片,每片 5MB,最多丢 15MB。

这就是标题里“只补 15MB”的出处。

二、为什么整文件上传一断就归零

一个 HTTP 请求传完,服务端才回 200。

在这之前,客户端手里没有“已确认到第几字节”的凭据。

连接一断,只能把整个请求重发。

我在页面里把这条规则写成:每断一次,已传字节清零,重试从 0 开始。

分片上传换了个思路:把确认点切小。

2048MB 按 5MB 切成 410 片,每片一个独立请求。

服务端每收好一片,就记一条已完成记录。

断网时,只有“在途”的 3 片需要重发,前面 318 片原样保留。

断点续传真正难的不是切片,是服务端要记住哪些片已经收好。

页面里用一个数组模拟这份记录:pending、transmitting、confirmed 三种状态。

只有整片传完才变绿。

断网那一瞬间,正在传的片变橙,不计数。

三、模型怎么算:参数、公式和三条边界

我把 8 个参数放在左侧,改任何一个都会重算。

参数默认值范围作用
文件大小2048 MB1~10240决定分片数
分片大小5 MB1~64决定每片请求的大小
带宽20 MB/s1~200换算传输时间
请求延迟50 ms0~1000每批请求的固定开销
并发分片数31~8同时在途的分片数
断网次数10~5注入几次失败
断网位置78%1~99%按已完成分片比例触发
恢复耗时8 s1~60断网后等多久重连

公式只有四条,页面上算的和我手算的一致。

  • 分片数 = ceil(2048 / 5) = 410。
  • 每片传输时间 = 5 / 20 = 0.25 秒。
  • 一批 3 片 = 0.75 秒,再加 50ms 请求延迟。
  • 整文件每断一次,已传字节清零重来。

图 2:模拟到 20 秒,绿色是已确认,蓝色是正在传的 3 片,有效吞吐 18.0MB/s

页面不联网,也不读你的真实文件。

所有数字都是按上面这组参数跑出来的模型结果。

真实网络还有 TCP 重传、丢包、服务端限速和分片落盘耗时,这里都没有模拟。

5MB 分片、3 并发、20MB/s 也只是演示值,不是推荐值。

四、断网瞬间:橙色方块和两行日志

图 3:断网瞬间,78% 处的 3 个分片变橙,日志同时记录整文件的 1.6GB 作废和分片的 15MB 丢失

图里有两行“网络中断”,说的是同一秒的两条链路。

整文件那条写的是“已传 1.6GB 全部作废”。

分片那条写的是“丢失 15.0MB,已确认分片保留”。

同样是断网,一边归零,一边只丢在途批次。

这就是两种方案的全部差别。

五、四组场景:断得越多,差距越大

页面给了四个预设按钮,点一下参数全变,表格立即重算。

场景整文件发送量整文件耗时整文件重传率分片发送量分片耗时分片重传率
断网 1 次3645.4 MB190.3 s43.8%2063.0 MB118.0 s0.7%
断网 3 次6840.3 MB366.1 s70.1%2093.0 MB135.5 s2.2%
慢网 2MB/s3645.4 MB1830.8 s43.8%2063.0 MB1053.2 s0.7%
完美网络2048.0 MB41.0 s0%2048.0 MB43.0 s0%

断 3 次那行最说明问题。

整文件发了 6.8GB,是文件本身的 3.3 倍。

分片只多发了 45MB。

慢网那行的时间差是 777.6 秒,差不多 13 分钟。

因为每次重传的都是 1.6GB,不是 15MB。

完美网络那行反过来:分片比整文件慢 2 秒。

137 批请求,每批 50ms 延迟,这笔开销跑不掉。

断点续传不是免费的,它拿一点点固定开销,换失败后的少重来。

表里是模型值;模拟器跑完是 117.8 秒,差 0.2 秒,来自最后一片只有 3MB。

六、开发时修掉的四个真 bug

第一个是重传率跑出 -173.1%。

页面只把“已确认分片”计入发送量,断网丢掉的那 15MB 没算。

分子变成负数,百分比就翻车了。

修复是把丢失批次在断网时计一次,重传确认时再计一次。

现在断网瞬间是 0.9%,跑完是 0.7%。

第二个是有效吞吐 50.4MB/s,比 20MB/s 的带宽还高。

代码拿文件大小除以耗时,可当时才传到 36%。

改成“已确认字节 / 耗时”后,同一时刻是 18.0MB/s。

第三个更隐蔽:断网 8 秒后,进度只到 360/410。

日志停在“第 405 片确认(360/410)”,下一行直接“完成”。

原因是批次按绝对时间排。

恢复后 8 秒被跳过,后面的批次全部过期,一帧只补一批,最后 3 片没传就判完成。

修复是把时间轴整体后移 8 秒,并从第一个未确认分片所在批次继续。

顺手还修了“断网 3 次只触发 1 次”:按批次排了 3 个断网点。

第四个是折线图。

每批 0.75 秒,速度在 0 和 20 之间跳,画出来是一排尖刺。

改成 0.5 秒平均后,曲线能看出趋势,标题也标了“0.5 秒平均”。

图 4:跑完后的界面,410 片全绿,分片模式总发送 2.0GB,整文件 3.6GB

七、准备环境:进入码道 Web 写需求

浏览器打开码道 Web 版:devcloud.cn-north-4.huaweicloud.com/chat?source…

登录后在对话框里写需求,不用装软件。

码道有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版。

需求里我写死了 8 个参数、四条公式和 5 个界面区域。

还加了一句“完成后打开预览”,省掉来回确认。

第一版交回来能跑,但有上面那四个问题。

改完再跑,410 片全部确认,表格和手算对上。

八、自己跑一遍:三步就能复现

源码在公开仓库,目录里就一个 index.html。

git clone https://gitcode.com/OPCTeam/demo_park.git
cd demo_park/codearts-resumable-upload-lab

也可以直接打开:gitcode.com/OPCTeam/dem…

不用装依赖,双击 index.html 就能跑。

第一步,保持默认参数,点“开始模拟”。

看 78% 附近那 3 个橙色方块,再看右侧日志的两行“网络中断”。

第二步,点“断网3次”预设,再点“重新模拟”。

对比表格里的 6.8GB 和 2.1GB,差距比断 1 次更明显。

第三步,把文件大小改成 3MB,分片还是 5MB,点“开始模拟”。

会看到红字“文件大小不能小于分片大小”,上一轮结果仍留在下方表格。

图 5:文件大小填 3MB、分片 5MB 时的错误提示,上一轮 3.6GB 对 2.0GB 的结果没有丢

失败路径不是摆设。

真实上传里,参数错、文件被占用、服务端拒绝都会发生。

页面至少要做到:给一句人话,别把上一轮结果清空。

九、边界:这是模型,不是公网压测

所有数字来自页内模型,不是真实公网上传的抓包结果。

页面没有真的读 2GB 文件,也没有发一个网络请求。

它算的是“按这组参数,两种协议要发多少字节、花多少时间”。

真实分片上传还要处理分片校验和、重试幂等、服务端清理过期分片、断点信息持久化。

刷新页面后还能不能续传,取决于你把已完成分片列表存在哪。

浏览器里可以放 IndexedDB,服务端要按 uploadId 存一份。

这些都没有在本页实现。

分片也不是越小越好。

5MB 是演示值,分片太小会让请求数暴涨,50ms 延迟乘上批次数,反而更慢。

分片太大,断网一次丢的就多。

真实系统要按带宽、延迟、失败率和存储成本一起调。

十、使用码道体会

  • 模拟规则写进需求,模型就没有自由发挥的空间。
  • 每个指标都要能在页面上和手算对上,对不上就是 bug。
  • 先跑失败路径再截图,读者才知道输入错了会怎样。
  • 模拟类文章必须把边界写在正文里,不能只写“实测”。
  • 预设按钮比让读者自己填 8 个参数更好用,也更容易复现。
  • 布局按内容反推列数,410 个方块才不会挤在顶部留一大片空白。

十一、结果与下一步

一次 78% 的断网,整文件发了 3.6GB、花了 190 秒。

同样一次断网,410 个 5MB 分片只补 15MB、118 秒传完。

断 3 次,差距从 1.5GB 拉到 4.7GB。

这就是断点续传的价值:不保证不出错,只保证出错后不用从头再来。

下一步想补真实文件切片上传、服务端分片记录和刷新后续传。

也想把分片大小做成扫描,看看 1MB、5MB、20MB 在同一组网络参数下谁更快。