你肯定见过这个场面:往网盘或公司服务器丢一个几个 G 的大文件,进度条慢吞吞往前爬,爬到 97%,网断了。重新点上传,一切从零开始,血压直接拉满。
但你也见过另一面:网盘上传一个几 G 的视频,一点按钮,「秒传成功」,进度条直接飞到头。同一个文件,体验差出十万八千里——这中间差的不是网速,是一套工程设计。今天就把大文件上传这套东西拆开讲明白,核心就四板斧。
先看直接传为什么必翻车
浏览器上传文件最朴素的姿势,就是把整个文件当成一个请求,一口气 POST 给服务器。文件小的时候没毛病,可文件到了 10G 这个量级,问题全冒出来了:
- •一断全废。传到 97% 断网,前面 9.7G 全部作废,从头再来,成本高到离谱;
- •内存扛不住。很多前端框架默认把整个文件读进内存再发,10G 的文件能把浏览器直接干崩;
- •超时是常态。一个请求挂几个小时,中间任何一层网关、代理的超时设置都能把它掐死;
- •失败没法定位。一次失败可能是网络抖了、磁盘满了、服务重启了,查起来全靠猜。
解法说来也简单,就八个字:化整为零,逐块推进。下面四板斧都是围绕这句话展开的。
第一板斧:分片上传——把大象切成块
思路很直接:把 10G 的文件按固定大小切成几百上千个小块,每块单独发一个请求。10G 切成 10MB 一块,就是 1024 个小任务,哪块失败就重传哪块,再也不用一朝回到解放前。
分片大小有讲究:5MB~20MB 是常见区间。切太小,HTTP 请求数暴增,光握手开销就吃掉不少速度;切太大,单块失败的重传成本又上去了。每个分片还要带上序号(第 1 块、第 2 块……),不然后端收到一堆块,不知道怎么拼回去。
前端切完了,后端怎么接?三种主流方案各有取舍:
![]()
编辑
生产环境的标准答案是对象存储 + Redis 记状态:分片本体扔给对象存储,传没传过由 Redis 说了算。一个简化的后端分片接口长这样:
![]()
编辑
每一块到齐后就触发异步合并,把几百个分片按序号拼回完整文件。合并环节还有个进阶技巧:用流式拷贝(零拷贝)代替普通读写,数据少几趟内存搬运,合并速度能快一个量级。
第二板斧:断点续传——摔了接着跑
分片只是让失败可恢复,还不够聪明——真正的关键是怎么知道哪些块已经传过了。做法是给文件算一个「指纹」:
- •上传前,前端把文件切成小块,逐块喂给哈希算法,算出整个文件的 MD5(或 SHA-256)指纹;
- •续传时,前端只带上这个指纹去问后端:这个文件你收到过哪几块?
- •后端用 Redis 记着每个指纹对应的已完成分片序号,直接把缺的列表还给前端;
- •前端只补缺的那几块,一块都不浪费。
这里有个技术细节很见功力:给 10G 的文件算指纹,如果一次性把整个文件读进内存,浏览器当场就崩了。正确姿势是边切边算——每次只读 2MB,算完一块丢一块,内存占用常年稳定在几十 MB。再把它丢进 Web Worker 独立线程里跑,主线程负责渲染界面,互不干扰:
![]()
编辑
同一个指纹还能玩出别的花样:用户换个浏览器、换台设备接着传,只要文件指纹没变,进度照样续上。
第三板斧:秒传——指纹一样就别传了
断点续传是「传了一半接着传」,秒传更狠——压根不用传。逻辑很简单:内容相同的文件,指纹必然相同。上传前先拿指纹去后端查一圈:
指纹已存在?后端直接返回现成文件的地址,前端弹个「上传成功」,实际上一字节都没走网络。这在企业内部场景尤其好用——所有人都在传同一份安装包、同一个素材包,据业内经验,秒传命中率能到 30% 以上,白赚的体验提升。
有人会较真:两份不同文件的指纹撞车了怎么办?哈希确实存在碰撞的可能,但概率低到可以忽略;真要较真,可以用 SHA-256 替代 MD5,或者再加文件大小、文件名双重校验,工程上早就把这条路堵死了。
第四板斧:多路并发——单车道变高速
前三板斧解决「稳」和「省」,最后这一斧解决「快」。串行一块一块传,带宽吃不满;把分片并发地同时传,速度立刻上一个台阶。
但并发不是越多越好。浏览器对同一域名的并发请求一般限制在 6 个左右,并发数开太大反而互相挤兑。3~5 个并发是甜点位。失败重试也别傻乎乎地立刻重试——网络抖动时大家一窝蜂重试只会更堵,正确做法是指数退避:第一次等 1 秒,第二次等 2 秒,第三次等 4 秒,给网络喘息的时间。一个轻量的并发池:
![]()
编辑
想再快还有两招:把上传域名拆成好几个(绕开浏览器 6 个并发的限制),或者根据网速动态调整分片大小——网快用大块,网慢切小块。
性能到底能快多少
拿 10GB 文件、10MB 分片、4 路并发这套典型配置算笔账:
![]()
编辑
而同样的文件如果不用这套方案:一次断网就前功尽弃,实际耗时完全无法预期。四板斧的本质,是把「听天由命」的上传变成可恢复、可复用、可加速的工程问题。
最后留个思考题:网盘的「秒传」的前提,是服务器上已经有人传过同样的文件——那你的私密文件,是不是早就躺在别人传过的记录里了?这个问题背后是另一套安全设计,感兴趣的评论区扣个 1,下期展开讲。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.