|
1 | 1 | --- |
2 | | -title: 文件断点续传的设计 |
| 2 | +title: 文件存储 |
3 | 3 | hide_title: true |
4 | 4 | sidebar_position: 3 |
5 | 5 | --- |
| 6 | + |
| 7 | + |
| 8 | +# 基于 Go 与 S3 的高效文件上传方案 —— 支持断点续传与秒传 |
| 9 | + |
| 10 | +在现代 App 与 Web 应用中,文件上传是常见且关键的功能。为应对传输中可能出现的中断、重复上传等问题,我们设计并实现了一套基于 **Go 服务端 + S3 存储** 的文件上传机制。该方案支持**断点续传** 与**秒传** ,并具备良好的**可扩展性** 和**极简客户端 SDK** ,实现客户端与 S3 直连,**数据流不经 API 服务中转** 。 |
| 11 | + |
| 12 | + |
| 13 | +## ✨ 设计目标 |
| 14 | + |
| 15 | + |
| 16 | +- ✅ 极简 SDK:客户端无需存储系统适配逻辑 |
| 17 | + |
| 18 | +- ✅ 降低服务器负载:文件流量不经由 API 服务 |
| 19 | + |
| 20 | +- ✅ 支持断点续传与秒传,提升用户体验 |
| 21 | + |
| 22 | +- ✅ 兼容任意 S3 接口,易于接入多种对象存储 |
| 23 | + |
| 24 | +- ✅ 可拓展支持非 S3 的 HTTP PUT 分片上传 |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +## 📦 上传流程 |
| 29 | + |
| 30 | + |
| 31 | +上传流程共分为五步: |
| 32 | + |
| 33 | + |
| 34 | +### 1. 获取分片大小 |
| 35 | + |
| 36 | +接口:`GET /object/part_limit` |
| 37 | + |
| 38 | +客户端首次上传前,请求服务端获取推荐的分片大小(如 5MB),并进行缓存。 |
| 39 | + |
| 40 | + |
| 41 | +### 2. 计算文件哈希 |
| 42 | + |
| 43 | +客户端将文件按分片大小切分,并计算每个分片的哈希值。然后将所有分片哈希拼接,最终计算出文件整体哈希(`file_hash`),用于秒传判断。 |
| 44 | + |
| 45 | + |
| 46 | +### 3. 初始化上传 |
| 47 | + |
| 48 | +接口:`POST /object/initiate_multipart_upload` |
| 49 | + |
| 50 | +客户端提交文件整体信息(如 hash、文件名、大小): |
| 51 | + |
| 52 | + |
| 53 | +- 若服务器发现该文件已存在(通过 `file_hash` 判断),则返回秒传成功的下载地址; |
| 54 | + |
| 55 | +- 若不存在,则返回每个分片的上传签名信息,包括: |
| 56 | + |
| 57 | + |
| 58 | + - 分片上传 URL |
| 59 | + |
| 60 | + - 必需的 Header(如 `Content-Type`, `Authorization`) |
| 61 | + |
| 62 | + - `PartNumber` 等标识 |
| 63 | + |
| 64 | + |
| 65 | +### 4. 上传分片(直传 S3) |
| 66 | + |
| 67 | + |
| 68 | +客户端使用返回的签名信息,将每个分片通过 HTTP PUT 直接上传至 S3,对应: |
| 69 | + |
| 70 | + |
| 71 | +- 上传过程中记录每一分片的 ETag 与 PartNumber |
| 72 | + |
| 73 | +- SDK 持久化这些信息,实现断点续传 |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | +> ⚠️ 文件内容始终不经由服务端,仅签名和元数据走 API。 |
| 78 | +
|
| 79 | + |
| 80 | +### 5. 完成上传 |
| 81 | + |
| 82 | +接口:`POST /object/complete_multipart_upload` |
| 83 | + |
| 84 | +客户端上传所有分片成功后,调用此接口提交分片信息列表。 |
| 85 | + |
| 86 | + |
| 87 | +- 服务端校验每个分片哈希及整体 hash |
| 88 | + |
| 89 | +- 校验通过后,发起 S3 的合并操作 |
| 90 | + |
| 91 | +- 最终返回文件的访问地址(可跳转到签名 S3 URL) |
| 92 | + |
| 93 | + |
| 94 | +## ⬇️ 下载流程 |
| 95 | + |
| 96 | + |
| 97 | +客户端下载时,从服务端获取临时签名下载地址(S3 Pre-signed URL),可设置权限与有效期控制。该地址可通过 API 统一跳转实现权限校验。 |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +## ✅ 特性一览 |
| 102 | + |
| 103 | +| 特性 | 说明 | |
| 104 | +| --- | --- | |
| 105 | +| 秒传支持 | 基于文件 hash 实现上传秒跳过 | |
| 106 | +| 断点续传 | 支持断线、异常退出后继续上传 | |
| 107 | +| 极简 SDK | 客户端无需签名逻辑,仅执行 PUT | |
| 108 | +| 存储兼容性强 | 支持任意兼容 HTTP PUT 的对象存储 | |
| 109 | +| 高可拓展性 | 可快速接入其他上传协议和存储系统 | |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +## ⚙️ 可扩展性设计 |
| 114 | + |
| 115 | + |
| 116 | +该方案以“服务端统一生成签名 + 客户端通用 PUT 上传”为核心架构,只要目标存储系统支持分片上传并接受带签名的 PUT 请求,即可无缝接入: |
| 117 | + |
| 118 | + |
| 119 | +- 支持 Amazon S3、MinIO、阿里云 OSS、腾讯云 COS 等 |
| 120 | + |
| 121 | +- 也可扩展支持其它上传服务 |
| 122 | + |
| 123 | + |
| 124 | +客户端代码不变,服务端扩展签名生成逻辑即可。 |
0 commit comments