分片上传详解
分片上传(Chunked Upload) 是一种将大文件分割成多个较小的片段(Chunks),分别上传到服务器,最后由服务器将这些片段重新合并成完整文件的技术方案,它是处理 GB 级别大文件上传的标准工业实践。
为什么需要分片上传?
在传统的单次请求上传模式中,面对大文件会遇到以下痛点:
- 网络稳定性差:文件越大,上传时间越长,一旦网络波动导致连接中断,整个文件必须从 0% 开始重新上传。
- 服务器限制:大多数 Web 服务器(如 Nginx, Tomcat)对单个请求的
client_max_body_size有限制,无法接收超大请求。 - 内存压力:服务器在接收大文件时,如果处理不当,可能会导致内存溢出(OOM)。
- 缺乏进度控制:难以实现精准的暂停、恢复和并发上传。
分片上传的核心流程
一个完整的分片上传流程通常分为以下五个阶段:
文件预处理(计算指纹)
在上传前,客户端通过 Spark-MD5 等库计算文件的唯一哈希值(File Hash)。
- 目的:作为文件的唯一标识符,用于实现 秒传(如果服务器已存在该哈希值的文件,直接返回成功)和 断点续传(查询已上传的分片索引)。
文件切片
利用 JavaScript 的 File 对象(继承自 Blob)提供的 slice() 方法,将文件切割成固定大小的块(例如每片 5MB)。
- 操作:
const chunk = file.slice(start, end);
分片上传
客户端将切片通过 HTTP 请求发送至服务器,每个请求通常携带以下参数:
- 文件唯一标识(Hash)
- 分片索引(Chunk Index)
- 总分片数(Total Chunks)
- 分片二进制数据(Blob/FormData)
并发控制
为了提高上传速度,通常会采用 并发上传(例如同时上传 3-6 个分片)。
- 实现:通过维护一个待上传队列和当前执行中的计数器,当一个分片完成时,立即从队列中取出下一个分片进行上传。
合并文件
当所有分片全部上传完成后,客户端发送一个 合并请求 通知服务器。
- 服务器操作:根据文件 Hash 找到对应的临时文件夹,按照分片索引顺序将所有小文件合并成一个大文件,并删除临时分片。
关键技术点与优化
- 秒传(Instant Upload):
在上传前先请求服务器检查该文件的 MD5 值是否存在,如果存在,直接跳过上传过程,直接标记为上传成功。 - 断点续传(Resumable Upload):
在开始上传前,客户端询问服务器:“该文件已经上传了哪些分片?”服务器返回已接收的分片索引列表,客户端过滤掉已上传的分片,仅上传剩余部分。 - 并发限制:
不能无限制地开启并发,否则会占用过多浏览器连接数或导致服务器压力过大,通常建议并发数设为 3-6 个。 - 错误重试机制:
对于上传失败的分片,应实现 指数退避重试 机制,避免因瞬时网络波动导致整个上传任务失败。
分片上传方案对比
| 特性 | 普通上传 | 分片上传 |
|---|---|---|
| 文件大小限制 | 受服务器配置限制 | 理论上无限制 |
| 网络波动影响 | 必须重新开始 | 仅需重传失败分片 |
| 上传速度 | 单线程,较慢 | 多线程并发,较快 |
| 用户体验 | 进度条简单,易中断 | 支持暂停/恢复/秒传 |
| 实现复杂度 | 低 | 高(需前后端协同) |
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/491650.html



