文件断点续传完整方案

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

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

技术栈示例: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 设置过期时间
  • 合并操作异步化
  • 上传限流(防止刷接口)
  • 上传鉴权(防止任意文件)

相关推荐
程序员泠零澪回家种桔子21 小时前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
CodeCaptain21 小时前
nacos-2.3.2-OEM与nacos3.1.x的差异分析
java·经验分享·nacos·springcloud
Anastasiozzzz1 天前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人1 天前
通过脚本推送Docker镜像
java·docker·容器
铁蛋AI编程实战1 天前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘1 天前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10111 天前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
摇滚侠1 天前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea
云姜.1 天前
java多态
java·开发语言·c++
李堇1 天前
android滚动列表VerticalRollingTextView
android·java