大文件分片上传需前后端协同、服务端状态管理与容错合并机制,核心是分片可重试、状态可查、失败不重传全量、最终可靠拼合。

大文件分片上传不是单纯把文件切开发多次请求,而是需要前后端协同、服务端状态管理、容错与合并能力的一整套机制。核心在于:**每个分片独立可重试、上传状态可查、失败不重传全量、最终能可靠拼合**。
一、接口设计要覆盖三个关键阶段
不能只暴露一个上传接口,必须拆成三个语义明确的 REST 端点:
- 初始化上传(POST /upload/init):客户端传文件名、总大小、MD5/SHA256(可选),服务端生成唯一 uploadId + fileId,返回分片大小(如 5MB)、最大并发建议、过期时间;
- 上传单个分片(PUT /upload/chunk):携带 uploadId、chunkIndex(从 0 开始)、totalChunks,Body 是二进制分片数据;Header 中建议带 X-Content-Range(如 bytes 0-5242879/104857599)和 X-File-Hash(当前分片哈希,用于校验);
- 合并文件(POST /upload/merge):传 uploadId 和完整文件名,服务端校验所有分片是否齐全、顺序是否正确、哈希是否匹配,然后按序合并并落盘或转存到对象存储(如 S3、OSS、UFile)。
二、服务端需维护分片元数据与状态
不能只靠文件系统临时目录硬存 .part 文件——那样无法做断点续传、无法跨节点扩展、也无法查进度。推荐做法:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用数据库(如 MySQL/PostgreSQL)建表记录:
upload_id、file_id、chunk_index、status(uploaded/pending/failed)、size、hash、created_at; - 分片文件本身建议存在高性能本地盘或对象存储的临时前缀下(如
uploads/{uploadId}/chunk_{index}),避免 NFS 或低性能共享存储; - 提供
GET /upload/status?uploadId=xxx接口,返回已上传分片索引集合(如[0,1,3,4]),前端据此决定重传哪些片。
三、前端切片与并发控制要务实
浏览器端用 File.slice() 切片,但注意实际策略:
- 分片大小建议 2–5MB:太小(如 256KB)HTTP 开销占比高;太大(如 20MB)单片失败重传成本高、内存压力大;
- 并发数设为 3–5:避免压垮后端或触发浏览器连接限制;可用
Promise.allSettled()控制并发批次; - 每个分片请求必须带唯一标识(uploadId + chunkIndex),且使用幂等设计(重复上传同一片应返回成功,不报错也不覆盖);
- 上传前可先调
POST /upload/check?fileMd5=xxx检查是否已存在完整文件(实现秒传)。
四、安全与健壮性不能妥协
生产环境必须考虑这些细节:
- 所有上传接口需鉴权(如 Bearer Token + 租户 ID),uploadId 必须绑定用户上下文,防止越权访问他人分片;
- 设置分片存储自动清理策略(如 24 小时未完成的 uploadId 对应分片全部删除);
- 合并操作需加分布式锁(如 Redis SETNX),防止并发 merge 导致文件损坏;
- 合并失败时保留原始分片,返回明确错误(如 “分片 #7 校验失败”),便于排查;
- 响应中统一返回
uploadId和fileId,后续下载、预览、删除都基于 fileId,与上传过程解耦。

















