文件断点续传完整方案

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

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

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

相关推荐
青春易逝丶8 分钟前
策略模式
java·开发语言·策略模式
贼爱学习的小黄17 分钟前
NC BIP参照开发
java·前端·nc
小江的记录本21 分钟前
【MyBatis-Plus】MyBatis-Plus的核心特性、条件构造器、分页插件、乐观锁插件
java·前端·spring boot·后端·sql·tomcat·mybatis
小张会进步21 分钟前
数组:二维数组
java·javascript·算法
vx-程序开发29 分钟前
springboot在线装修管理系统-计算机毕业设计源码56278
java·c语言·spring boot·python·spring·django·php
大傻^32 分钟前
Spring AI Alibaba 可观测性实践:AI应用监控与链路追踪
java·人工智能·后端·spring·springaialibaba
云烟成雨TD37 分钟前
Spring AI Alibaba 1.x 系列【1】阿里巴巴 AI 生态
java·人工智能·spring
诗人不写诗41 分钟前
spring是如何组织切面的
java·后端·spring
大傻^1 小时前
Spring AI Alibaba Agent开发:基于ChatClient的智能体构建模式
java·数据库·人工智能·后端·spring·springaialibaba
li星野1 小时前
C++面试真题分享20260320
java·c++·面试