2GB 的文件传到 78%,网断了。
整文件重传从 0 开始,这一趟一共发了 3.6GB,耗时 190.3 秒。
切成 410 个 5MB 分片再传,只补了 15MB,118 秒传完。

在线案例与源码:gitcode.com/OPCTeam/dem… 成品只有一个 index.html,双击就能打开。
一、先看差在哪:一次断网差 1.5GB
两条链路跑的是同一份 2048MB 文件、同一次 78% 断网、同样的 8 秒恢复时间。
网上一搜“断点续传”,大多是贴一段切片代码,很少给失败前后的字节对比。
我把两种传法放进同一个页面,用同一组参数跑了一遍。
| 指标 | 整文件上传 | 5MB 分片 + 断点续传 | 差值 |
|---|---|---|---|
| 总线发送量 | 3645.4 MB | 2063.0 MB | 少 1582.4 MB |
| 总耗时 | 190.3 s | 118.0 s | 少 72.3 s |
| 重传字节 | 1597.4 MB | 15.0 MB | 少 1582.4 MB |
| 重传率 | 43.8% | 0.7% | 降 43.1 个点 |
| 有效吞吐 | 10.8 MB/s | 17.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 MB | 1~10240 | 决定分片数 |
| 分片大小 | 5 MB | 1~64 | 决定每片请求的大小 |
| 带宽 | 20 MB/s | 1~200 | 换算传输时间 |
| 请求延迟 | 50 ms | 0~1000 | 每批请求的固定开销 |
| 并发分片数 | 3 | 1~8 | 同时在途的分片数 |
| 断网次数 | 1 | 0~5 | 注入几次失败 |
| 断网位置 | 78% | 1~99% | 按已完成分片比例触发 |
| 恢复耗时 | 8 s | 1~60 | 断网后等多久重连 |
公式只有四条,页面上算的和我手算的一致。
- 分片数 = ceil(2048 / 5) = 410。
- 每片传输时间 = 5 / 20 = 0.25 秒。
- 一批 3 片 = 0.75 秒,再加 50ms 请求延迟。
- 整文件每断一次,已传字节清零重来。

页面不联网,也不读你的真实文件。
所有数字都是按上面这组参数跑出来的模型结果。
真实网络还有 TCP 重传、丢包、服务端限速和分片落盘耗时,这里都没有模拟。
5MB 分片、3 并发、20MB/s 也只是演示值,不是推荐值。
四、断网瞬间:橙色方块和两行日志

图里有两行“网络中断”,说的是同一秒的两条链路。
整文件那条写的是“已传 1.6GB 全部作废”。
分片那条写的是“丢失 15.0MB,已确认分片保留”。
同样是断网,一边归零,一边只丢在途批次。
这就是两种方案的全部差别。
五、四组场景:断得越多,差距越大
页面给了四个预设按钮,点一下参数全变,表格立即重算。
| 场景 | 整文件发送量 | 整文件耗时 | 整文件重传率 | 分片发送量 | 分片耗时 | 分片重传率 |
|---|---|---|---|---|---|---|
| 断网 1 次 | 3645.4 MB | 190.3 s | 43.8% | 2063.0 MB | 118.0 s | 0.7% |
| 断网 3 次 | 6840.3 MB | 366.1 s | 70.1% | 2093.0 MB | 135.5 s | 2.2% |
| 慢网 2MB/s | 3645.4 MB | 1830.8 s | 43.8% | 2063.0 MB | 1053.2 s | 0.7% |
| 完美网络 | 2048.0 MB | 41.0 s | 0% | 2048.0 MB | 43.0 s | 0% |
断 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 秒平均”。

七、准备环境:进入码道 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,点“开始模拟”。
会看到红字“文件大小不能小于分片大小”,上一轮结果仍留在下方表格。

失败路径不是摆设。
真实上传里,参数错、文件被占用、服务端拒绝都会发生。
页面至少要做到:给一句人话,别把上一轮结果清空。
九、边界:这是模型,不是公网压测
所有数字来自页内模型,不是真实公网上传的抓包结果。
页面没有真的读 2GB 文件,也没有发一个网络请求。
它算的是“按这组参数,两种协议要发多少字节、花多少时间”。
真实分片上传还要处理分片校验和、重试幂等、服务端清理过期分片、断点信息持久化。
刷新页面后还能不能续传,取决于你把已完成分片列表存在哪。
浏览器里可以放 IndexedDB,服务端要按 uploadId 存一份。
这些都没有在本页实现。
分片也不是越小越好。
5MB 是演示值,分片太小会让请求数暴涨,50ms 延迟乘上批次数,反而更慢。
分片太大,断网一次丢的就多。
真实系统要按带宽、延迟、失败率和存储成本一起调。
十、使用码道体会
- 模拟规则写进需求,模型就没有自由发挥的空间。
- 每个指标都要能在页面上和手算对上,对不上就是 bug。
- 先跑失败路径再截图,读者才知道输入错了会怎样。
- 模拟类文章必须把边界写在正文里,不能只写“实测”。
- 预设按钮比让读者自己填 8 个参数更好用,也更容易复现。
- 布局按内容反推列数,410 个方块才不会挤在顶部留一大片空白。
十一、结果与下一步
一次 78% 的断网,整文件发了 3.6GB、花了 190 秒。
同样一次断网,410 个 5MB 分片只补 15MB、118 秒传完。
断 3 次,差距从 1.5GB 拉到 4.7GB。
这就是断点续传的价值:不保证不出错,只保证出错后不用从头再来。
下一步想补真实文件切片上传、服务端分片记录和刷新后续传。
也想把分片大小做成扫描,看看 1MB、5MB、20MB 在同一组网络参数下谁更快。