文件断点续传完整方案

文件断点续传(断点上传)完整实现方案(后端视角)

适用场景:大文件上传、弱网环境、移动端上传、失败可恢复、避免重复上传

技术栈示例:HTTP + Java + Redis + MySQL + 对象存储(OSS / COS / S3)


一、什么是文件断点续传

断点续传 = 文件分片上传 + 状态记录 + 可恢复上传

核心思想:

  • 把一个大文件切成多个 Chunk(分片)
  • 每个分片单独上传
  • 服务端记录已上传分片
  • 中断后只补传缺失分片

一句话:上传失败 ≠ 重来,而是从"断点"继续


二、为什么一定要用断点上传

1️⃣ 解决的问题

问题 普通上传 断点上传
大文件 ❌ 容易失败 ✅ 稳定
网络抖动 ❌ 重来 ✅ 续传
用户体验 ❌ 崩溃 ✅ 友好
带宽浪费 ❌ 严重 ✅ 可控

2️⃣ 典型场景

  • 视频 / 音频 / 安装包
  • 企业网盘
  • IM 文件发送
  • 后台管理系统上传 Excel / 压缩包

三、整体架构设计(后端视角)

复制代码
Client
  ↓(分片)
Upload API
  ↓
Redis(上传状态)
  ↓
临时分片存储(磁盘 / OSS)
  ↓
合并服务
  ↓
最终文件存储(OSS / 本地)

关键点:

  • Redis:记录分片上传进度
  • OSS:避免服务端磁盘爆炸
  • 合并操作:必须保证原子性

四、核心概念定义

1️⃣ 文件唯一标识(fileId)

通常使用:

复制代码
fileId = MD5(文件内容)

作用:

  • 秒传(已存在直接返回)
  • 断点识别
  • 去重

2️⃣ 分片参数

参数 含义
chunkIndex 当前分片索引(从 0 开始)
chunkSize 分片大小(如 5MB)
totalChunks 总分片数
fileId 文件唯一标识

五、接口设计(非常关键)

1️⃣ 初始化上传

接口

复制代码
POST /upload/init

请求

json 复制代码
{
  "fileId": "md5值",
  "fileName": "test.zip",
  "fileSize": 10240000,
  "chunkSize": 5242880
}

返回

json 复制代码
{
  "uploadedChunks": [0,2,3]
}

👉 客户端只上传缺失分片


2️⃣ 上传分片

复制代码
POST /upload/chunk

参数

  • fileId
  • chunkIndex
  • MultipartFile chunk

服务端逻辑

  1. 校验分片合法性
  2. 保存分片
  3. Redis 记录已上传 chunkIndex

3️⃣ 合并分片

复制代码
POST /upload/merge

流程

  1. 校验所有分片是否齐全
  2. 按顺序合并
  3. 生成最终文件
  4. 清理分片 & Redis

六、Redis 设计(重点)

1️⃣ Key 设计

复制代码
upload:{fileId}

2️⃣ Value 结构

text 复制代码
Set<Integer> uploadedChunks

或:

text 复制代码
Bitmap(更省内存)

3️⃣ 为什么用 Redis

  • 高并发
  • 原子操作
  • 进度查询快
  • 自动过期

七、Java 后端核心代码示例

1️⃣ 保存分片

java 复制代码
String key = "upload:" + fileId;
redisTemplate.opsForSet().add(key, chunkIndex);

2️⃣ 校验是否上传完成

java 复制代码
Long count = redisTemplate.opsForSet().size(key);
if (count == totalChunks) {
    // 允许合并
}

八、分片合并的坑(一定要看)

❌ 常见错误

  • 合并过程中进程挂了
  • 多个请求同时触发 merge
  • 合并顺序错乱

✅ 正确做法

  1. 分布式锁

    lock:merge:{fileId}

  2. 顺序合并

    chunk_0 → chunk_1 → chunk_2

  3. 临时文件 + rename

rename 在 Linux 下是原子操作


九、秒传是怎么实现的

流程:

  1. 客户端计算 MD5
  2. init 接口检查数据库
  3. 已存在 → 直接返回 URL
java 复制代码
if (fileExists(fileId)) {
    return "秒传成功";
}

本质:去重,不是快,是不传


十、断点上传 vs 对象存储直传

方案 特点
后端中转 控制力强
OSS 分片上传 性能最好
OSS + 回调 企业级最优解

强烈建议:

大文件 = OSS 分片上传 + 后端校验


十一、生产级优化建议

  • 分片大小:5MB ~ 10MB
  • Redis Key 设置过期时间
  • 合并操作异步化
  • 上传限流(防止刷接口)
  • 上传鉴权(防止任意文件)

相关推荐
像少年啦飞驰点、2 小时前
零基础入门 Spring Boot:从‘Hello World’到可部署微服务的完整学习路径
java·spring boot·web开发·编程入门·后端教程
m0_748248652 小时前
C++正则表达式攻略:从基础到高级应用
java·c++·正则表达式
墨雨晨曦882 小时前
leedcode刷题总结
java·开发语言
qq_12498707532 小时前
基于SpringBoot的闪电队篮球俱乐部管理系统的设计与开发(源码+论文+部署+安装)
java·数据库·spring boot·后端·spring·毕业设计·计算机毕业设计
a努力。2 小时前
中国邮政Java面试被问:MySQL的ICP(索引条件下推)优化原理
java·开发语言·数据仓库·面试·职场和发展·重构·maven
猿小羽2 小时前
Spring AI + MCP 实战:构建企业级 Agent 生态的基石
java·spring boot·llm·agent·spring ai·mcp·artificial intelligence
茶本无香2 小时前
设计模式之八: 适配器模式解释及应用
java·设计模式·适配器模式
青槿吖2 小时前
【趣味图解】线程同步与通讯:从抢奶茶看透synchronized、ReentrantLock和wait/notify
java·开发语言·jvm·算法
jiayong232 小时前
MQ基础概念面试题
java·kafka·rabbitmq·rocketmq