Skip to content

大文件上传

背景

对于企业资料、会议视频等大文件的上传,如果不作特殊处理,将遇到以下问题:

  1. 网络中断、程序异常退出等问题导致文件上传失败,从而不得不全部重新上传。
  2. 同一文件被不同用户反复上传,白白占用网络和服务器存储资源。

因此,需要一个针对大文件上传的方案来解决上述问题。

实现思路

大文件上传的普遍方案是 文件分片上传

如果把文件上传看做是一个不可分割的事务,那么分片的目标就是把一个耗时的大事务划分为一个一个的小事务。

分片上传的主要障碍集中在:

  1. 如何减少页面阻塞
  2. 前后端如何协调
  3. 代码如何组织
  4. 前端代码中的复杂逻辑
  5. BFF 代码中的复杂逻辑

  1. 前端 chunk 切片,例如 1024MB 的文件,每片 4~5MB 左右。

    片太小会产生过多请求、片太大单片失败重传代价高。移动网络或弱网可降到 1-2MB;内网或稳定环境可以增大。

  2. 将所有切片数据传递给后端,并且为每个切片通过(hash + index)进行标识。

    前端限制并发上传数(常见 3–6 个并行请求),避免浏览器或后端压力。

  3. 后端组合切片。

核心点

  • 切片上传:将大文件分成多个小块,逐个上传。
  • 断点续传:记录上传进度,支持中断后继续上传。
后续优化点
  1. 前端切片时,为了避免主进程卡顿,使用 web worker 多线程切片。
  2. 支持“秒传”,计算文件整体 hash(如:sha-256)判断文件是否已存在,避免重复上传。

如何减少页面阻塞?

分片上传的一个首要目标就是要尽量避免相同的分片重复上传。服务器必须要能够识别来自各个客户端的各个上传请求中,是否存在与过去分片相同的上传请求。

服务器如何识别哪些分片是相同的呢?

首先需要对相同下一个准确的定义:文件内容一样即为相同

可是对文件内容进行二进制的对比是一个非常耗时的操作,于是可以选择 基于内容的 hash 来进行对比

hash 是一种算法,可以将任何长度的数据转换为定长的数据,常见的 hash 算法包括 MD5、SHA-1
可以使用第三方库 Spark-MD5

基于 MIT 许可发布