分片上传失败后只需精准重试失败分片,关键在于服务端持久化接收状态并返回已传分片列表,客户端据此跳过已成功部分;重试需携带唯一标识、幂等元数据,并采用指数退避策略,合并前须校验完整性,避免重复操作。

大文件分片上传中,某个分片上传失败后需要重试,关键不是“重新传整个文件”,而是精准重试失败的那一个(或几个)分片,并在服务端合并时跳过已成功接收的部分。
明确失败分片的标识和状态同步
客户端必须能唯一识别每个分片,通常用 文件唯一 ID + 分片序号 + 分片哈希(可选) 组合。上传前先向服务端发起预检请求(如 /upload/prepare),获取已成功接收的分片列表(例如返回 [0, 1, 3, 4]),客户端据此跳过这些分片,只重试缺失或失败的(如 2 和 5)。
- 避免靠客户端本地记录判断成功与否——页面刷新、崩溃会导致状态丢失
- 服务端需持久化每个文件的分片接收状态(如 Redis 或数据库中存
{fileId: "abc", receivedChunks: [0,1,3]}) - 重试请求应携带相同分片元数据(如
chunkIndex=2、totalChunks=10、fileHash),便于服务端校验幂等性
前端实现带指数退避的分片重试逻辑
不要立即无限重试。用 fetch 或 axios 配合 abortController 控制单次请求,并在失败后延迟重试:
- 初始延迟 500ms,每次失败翻倍(500 → 1000 → 2000ms),最多重试 3 次
- 网络异常(如 timeout、network error)才重试;HTTP 4xx 错误(如 400、401)通常不该重试,需提示用户检查参数或登录态
- 重试时复用原始 Blob 切片(
file.slice(start, end)),不重新生成,确保内容一致
服务端合并前校验并跳过缺失分片
当所有分片“声称”上传完成,客户端调用合并接口(如 POST /upload/merge)时,服务端不能直接拼接磁盘文件,而要:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 查数据库/缓存,确认该文件的
receivedChunks是否完整覆盖0到totalChunks - 1 - 若不完整,返回 409 Conflict + 缺失分片列表(如
{"missing": [2,5]}),前端收到后触发对应分片重试 - 只有状态完整才执行合并:按序读取各分片临时文件,流式写入目标文件,完成后清理临时分片
防止重复合并与并发冲突
多个重试请求可能同时触发合并,导致文件损坏或重复写入:
- 合并接口加分布式锁(如 Redis SETNX
lock:merge:abc),超时设为 5 分钟 - 合并成功后立即将文件状态置为
merged,后续合并请求直接返回成功响应 - 每个分片上传成功后,服务端异步触发一次“检查是否可合并”,但仅当所有分片就位才真正执行
核心是前后端协同维护分片状态,把“重试”收敛到具体索引,而不是盲目重发。服务端不信任客户端的“我传完了”,始终以自身存储为准。

















