公司动态
大文件上传后端落地方案
https://juejin.cn/post/7571355989133099023 掘金文章大文件上传后端落地方案Context这篇文章的核心观点是大文件上传不能简单设计成一个同步/upload接口而应抽象为“上传任务 分片状态 可恢复流程 异步后处理”的完整系统。目标是支持 GB 级文件、弱网断点续传、秒传、集群部署、失败可恢复、状态可审计并避免同步上传和同步合并带来的超时、磁盘堆积、状态不一致等问题。本方案适合作为后续在后端系统中实现大文件上传能力的工程化设计依据。推荐方案1. 总体架构采用分层设计Controller暴露上传任务、分片上传、进度查询、提交合并、取消上传接口。Application Service编排上传任务状态、幂等校验、权限校验、分片完整性校验。Storage Service屏蔽本地文件、NAS、MinIO、OSS、S3 等存储差异。Async Worker异步执行文件合并、hash 校验、内容安全检测、临时文件清理。DB作为上传任务和分片状态的最终状态源。Redis用于分布式锁、限流、短期进度缓存不作为最终状态源。核心原则应用服务无状态分片不能依赖单机本地磁盘生产集群优先使用对象存储或共享存储。2. 核心接口设计建议接口拆分如下POST /files/multipart/init初始化上传任务。入参fileName、fileSize、fileHash、chunkSize、totalChunks、contentType、bizType。行为先检查秒传若文件已存在直接返回文件信息否则创建或复用上传任务并返回uploadId和已上传分片列表。POST /files/multipart/chunks上传单个分片。入参uploadId、chunkIndex、chunkHash、file。行为校验任务状态、分片序号、大小、hash重复上传相同分片直接返回成功hash 不一致则拒绝。GET /files/multipart/{uploadId}/progress查询上传进度。返回任务状态、总分片数、已上传分片索引、失败分片、合并状态、错误信息。POST /files/multipart/{uploadId}/complete提交合并。行为校验分片完整性后将任务状态改为MERGING或投递异步合并任务接口快速返回。DELETE /files/multipart/{uploadId}取消上传。行为任务状态改为CANCELLED异步清理临时分片。3. 数据库设计建议至少三张表upload_task保存上传任务主状态。关键字段idupload_id全局唯一上传任务 IDfile_hashfile_namefile_size必须使用 Long/BIGINTchunk_sizetotal_chunksuploaded_chunksstatusINIT / UPLOADING / MERGING / SUCCESS / FAILED / CANCELLED / EXPIREDfile_id合并成功后的最终文件 IDerror_msgexpire_timecreate_bycreate_timeupdate_time索引建议唯一索引upload_id普通索引file_hash, file_size普通索引status, expire_timeupload_chunk保存每个分片的上传状态。关键字段idupload_idchunk_indexchunk_hashchunk_sizestorage_pathstatuscreate_timeupdate_time索引建议唯一索引upload_id, chunk_indexfile_info保存最终文件元数据。关键字段idfile_hashfile_namefile_sizecontent_typestorage_pathurlstatuscreate_bycreate_time索引建议普通索引或唯一策略file_hash, file_size是否允许同 hash 文件多业务复用需要结合权限和租户模型决定。多租户系统不要简单全局秒传至少要校验租户、用户或业务域权限。4. 状态机设计推荐状态流转INIT - UPLOADING - MERGING - SUCCESS | | v v FAILED FAILED | v EXPIRED 任意未完成状态 - CANCELLED约束MERGING状态禁止继续接收分片。SUCCESS、CANCELLED、EXPIRED为终态。状态更新使用 CAS 条件例如where upload_id ? and status ?。complete可以重试但同一uploadId同一时间只能有一个合并任务执行。5. 分片上传与断点续传客户端流程计算文件 hash。调用 init。根据服务端返回的已上传分片列表跳过已完成分片。并发上传缺失分片。所有分片完成后调用 complete。轮询 progress 或接收通知等待合并完成。服务端要求以uploadId chunkIndex作为分片幂等键。重复上传相同 hash 的分片直接返回成功。重复上传但 hash 不一致必须拒绝避免脏数据覆盖。分片大小、分片序号、总分片数必须校验。断点续传依据数据库分片记录而不是浏览器缓存或服务端内存。6. 秒传设计初始化时根据fileHash fileSize查询最终文件表。命中后还必须校验文件状态为可用。当前用户、租户或业务域有权限使用该文件。如果文件有安全扫描状态必须是扫描通过。通过后直接创建业务引用或返回文件 ID不再上传分片。7. 异步合并设计complete接口不建议同步合并大文件避免 HTTP 超时和应用线程阻塞。推荐流程校验任务存在且状态为UPLOADING。校验分片数量完整。使用状态 CAS 改为MERGING。投递 MQ 或写入合并任务表。Worker 获取任务后加分布式锁。按chunkIndex顺序流式合并或调用对象存储 multipart complete。合并后重新计算文件 hash与客户端 hash 比对。写入最终文件表。上传任务改为SUCCESS。异步删除临时分片。如果合并失败记录失败原因。任务改为FAILED。保留分片一段时间允许用户重试 complete。8. 幂等与并发控制需要重点保证以下幂等场景init 重复调用返回同一个未完成任务或命中秒传。chunk 重复上传相同分片相同 hash 返回成功。complete 重复调用已在合并中则返回MERGING已成功则返回最终文件。abort 重复调用终态返回成功。并发控制建议DB 唯一索引防重复分片。状态 CAS 防止并发状态错乱。Redis 或 DB 锁防止并发合并。上传分片接口限制单用户、单任务、单租户并发数。9. 集群部署要求生产环境不建议把分片存储在应用本机目录。推荐优先级对象存储 multipart upload最适合云环境和大文件。MinIO / S3 兼容存储适合私有化部署。NAS / NFS可用但要关注 IO、锁和稳定性。本地磁盘仅适合单机开发或测试。集群部署中DB 是最终状态源。Redis 只做锁、限流和缓存。Worker 可多实例部署但同一任务只允许一个 Worker 合并。临时分片路径必须带uploadId隔离。10. 安全控制必须校验登录态和权限。租户隔离。文件大小上限。分片大小上限。文件后缀白名单或黑名单。MIME 类型。文件魔数。文件名路径规范化禁止../路径穿越。hash 与实际内容一致。上传频率和并发数。如涉及医疗、政企、知识库等场景还应增加病毒扫描。敏感内容检测。文件访问审计。文件加密存储。下载鉴权和防盗链。11. 清理机制需要定时任务清理超过expire_time的INIT / UPLOADING任务。长时间卡在MERGING的任务。FAILED / CANCELLED / EXPIRED的临时分片。孤儿分片。未被业务引用的最终文件。清理任务要求分页扫描。限速删除。可重试。删除前更新任务状态避免边上传边删除。记录清理日志和删除结果。12. 监控告警核心指标初始化任务数。分片上传成功率。分片上传平均耗时和 P95/P99。合并任务耗时。合并失败率。秒传命中率。临时分片占用空间。超时任务数量。卡在MERGING的任务数量。告警建议合并失败率突增。临时存储空间超过阈值。MERGING任务超过指定时长。分片上传错误率突增。对象存储访问异常。日志建议每个 uploadId 全链路打印。chunk 上传失败记录原因。complete 和 merge 记录状态流转。清理任务记录删除数量和失败原因。13. 测试验证功能测试普通大文件上传成功。秒传命中。断点续传。重复分片上传。乱序分片上传。缺少分片时提交合并失败。合并成功后 hash 校验正确。取消上传后不能继续上传。并发测试同一文件多用户并发 init。同一 uploadId 并发 chunk。同一 uploadId 并发 complete。Worker 多实例并发消费。异常测试上传中断后恢复。合并中服务重启。对象存储短暂失败。Redis 锁失效。DB 唯一索引冲突。临时文件被误删。性能测试1GB、5GB、10GB 文件上传。不同 chunkSize 下的吞吐与耗时。高并发分片上传。合并阶段 IO 压力。临时存储空间增长与清理速度。后续实现时建议修改的关键文件实施前应读取这些文件确认现有普通上传、分片表、文件表、安全文件服务和权限模型避免重复造轮子。验证方式端到端验证建议本地启动后端服务。使用测试脚本模拟 init、chunk、progress、complete 全流程。使用同一个文件重复上传验证秒传。中断部分分片后重新上传验证断点续传。并发调用 complete 验证幂等和锁。人为删除分片或修改 hash 验证异常路径。观察数据库任务状态、分片记录、最终文件记录是否一致。观察日志、指标和临时文件清理结果。主要风险只做接口拆分但不做状态机会导致上传状态不可控。只依赖本机磁盘会导致集群部署后分片分散。同步合并大文件会造成接口超时和线程阻塞。没有幂等设计会在重试和并发场景产生重复数据或脏数据。没有清理机制会持续占用磁盘或对象存储空间。全局秒传不做权限隔离可能造成越权访问文件。推荐一个AI聚合站https://codex.sundavip.com