跳到主要内容

基于 Go 与 S3 的高效文件上传方案 —— 支持断点续传与秒传

在现代 App 与 Web 应用中,文件上传是常见且关键的功能。为应对传输中可能出现的中断、重复上传等问题,我们设计并实现了一套基于 Go 服务端 + S3 存储 的文件上传机制。该方案支持断点续传秒传 ,并具备良好的可扩展性极简客户端 SDK ,实现客户端与 S3 直连,数据流不经 API 服务中转

✨ 设计目标

  • ✅ 极简 SDK:客户端无需存储系统适配逻辑

  • ✅ 降低服务器负载:文件流量不经由 API 服务

  • ✅ 支持断点续传与秒传,提升用户体验

  • ✅ 兼容任意 S3 接口,易于接入多种对象存储

  • ✅ 可拓展支持非 S3 的 HTTP PUT 分片上传

📦 上传流程

上传流程共分为五步:

1. 获取分片大小

接口:GET /object/part_limit

客户端首次上传前,请求服务端获取推荐的分片大小(如 5MB),并进行缓存。

2. 计算文件哈希

客户端将文件按分片大小切分,并计算每个分片的哈希值。然后将所有分片哈希拼接,最终计算出文件整体哈希(file_hash),用于秒传判断。

3. 初始化上传

接口:POST /object/initiate_multipart_upload

客户端提交文件整体信息(如 hash、文件名、大小):

  • 若服务器发现该文件已存在(通过 file_hash 判断),则返回秒传成功的下载地址;

  • 若不存在,则返回每个分片的上传签名信息,包括:

  • 分片上传 URL

  • 必需的 Header(如 Content-Type, Authorization

  • PartNumber 等标识

4. 上传分片(直传 S3)

客户端使用返回的签名信息,将每个分片通过 HTTP PUT 直接上传至 S3,对应:

  • 上传过程中记录每一分片的 ETag 与 PartNumber

  • SDK 持久化这些信息,实现断点续传

⚠️ 文件内容始终不经由服务端,仅签名和元数据走 API。

5. 完成上传

接口:POST /object/complete_multipart_upload

客户端上传所有分片成功后,调用此接口提交分片信息列表。

  • 服务端校验每个分片哈希及整体 hash

  • 校验通过后,发起 S3 的合并操作

  • 最终返回文件的访问地址(可跳转到签名 S3 URL)

⬇️ 下载流程

客户端下载时,从服务端获取临时签名下载地址(S3 Pre-signed URL),可设置权限与有效期控制。该地址可通过 API 统一跳转实现权限校验。

✅ 特性一览

特性说明
秒传支持基于文件 hash 实现上传秒跳过
断点续传支持断线、异常退出后继续上传
极简 SDK客户端无需签名逻辑,仅执行 PUT
存储兼容性强支持任意兼容 HTTP PUT 的对象存储
高可拓展性可快速接入其他上传协议和存储系统

⚙️ 可扩展性设计

该方案以“服务端统一生成签名 + 客户端通用 PUT 上传”为核心架构,只要目标存储系统支持分片上传并接受带签名的 PUT 请求,即可无缝接入:

  • 支持 Amazon S3、MinIO、阿里云 OSS、腾讯云 COS 等

  • 也可扩展支持其它上传服务

客户端代码不变,服务端扩展签名生成逻辑即可。