1. 大文件上传的痛点与解决方案
大文件上传一直是Web开发中的经典难题。最近在重构一个医疗影像管理系统时,我遇到了SpringBoot应用在上传2GB以上DICOM文件时频繁卡死的问题。客户端进度条卡在50%不动,服务器CPU占用率飙升到100%,最终导致连接超时。这种场景在视频平台、云存储服务、企业文档系统中同样常见。
传统表单上传采用一次性加载整个文件到内存的方式,存在三个致命缺陷:
- 内存溢出风险:Servlet 3.0规范中默认的multipart配置会将文件暂存内存,超过阈值才写入磁盘
- 网络中断重传成本高:一个5GB文件上传到99%时失败,必须从头开始
- 服务器资源占用不可控:大文件上传会长时间占用线程和内存
分块上传技术将大文件切割成等大的chunk(通常1-5MB),通过以下机制解决上述问题:
- 内存控制:每个chunk独立上传,内存中只保留当前分块数据
- 断点续传:记录已上传分块,网络恢复后继续上传剩余部分
- 并行加速:浏览器可并发上传多个分块(通常4-6个并发)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 分块上传核心实现
2.1 前端分块切割方案
使用File API的slice方法实现文件切割,这是浏览器原生支持的二进制操作:
javascript复制function createChunks(file, chunkSize) {
const chunks = []
let start = 0
while (start < file.size) {
const end = Math.min(start + chunkSize, file.size)
chunks.push(file.slice(start, end))
start = end
}
return chunks
}
关键参数选择建议:
- 分块大小:1MB-5MB(过小导致请求数爆炸,过大失去分块意义)
- 并发数:navigator.hardwareConcurrency || 4(根据CPU核心数动态调整)
- 进度计算:已上传字节数 / 总字节数 * 100
实测发现:Chrome对2MB以下分块处理效率最高,Safari则需要4MB以上分块才能发挥性能
2.2 服务端校验与合并
SpringBoot接收端需要三个核心接口:
java复制// 分块上传接口
@PostMapping("/upload/chunk")
public ResponseEntity<String> uploadChunk(
@RequestParam String fileMd5,
@RequestParam Integer chunkIndex,
@RequestParam MultipartFile chunk) {
String chunkPath = TEMP_DIR + fileMd5 + "/" + chunkIndex;
chunk.transferTo(new File(chunkPat
