文件断点续传完整方案

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

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

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

相关推荐
tianyu2343 小时前
Java 正则表达式终极指南:从 Pattern 到 Matcher,从双重转义到性能优化,一篇全搞定
java·开发语言·正则表达式·group·find·pattern·matcher
Emily156853598705 小时前
Emerson 1C31129G03 Analog Input Module
java·开发语言·前端·plc·emerson·1c31129g03·input module
就叫_这个吧10 小时前
Java递归方法实现面包屑导航
java·开发语言
fīɡЙtīиɡ ℡10 小时前
AI 应用系统设计
java·开发语言·人工智能
城管不管10 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
码匠许师傅10 小时前
【C++ 面试真题】26. 聊聊 C++ 的智能指针
java·c++·面试
AI绘画哇哒哒10 小时前
【建议收藏!】35岁后端血泪忠告,这3类人别硬转Agent(过来人亲述)
java·人工智能·后端·ai·程序员·大模型·agent
最强小杰11 小时前
gpt-5.6-sol 频繁报 503 怎么办?区分容量熔断和限速 429 的排查方法 + 可复用 retry wrapper
java·人工智能·gpt·ai
吠品13 小时前
Wine 在 Linux 上运行 Windows 软件完整指南
java·linux·服务器
亚历克斯神14 小时前
智能搜索系统的升级复盘——从 Elasticsearch 到混合检索的检索质量提升
java·spring·微服务