@@ -5,89 +5,120 @@ sidebar_position: 3
55---
66
77
8- # 基于 Go 与 S3 的高效文件上传实现: 支持断点续传与秒传
8+ # 基于 Go 与 S3 的高效大文件上传方案 —— 支持断点续传与秒传
99
10+ 在现代 App 与 Web 应用中,大文件上传是常见且关键的功能。为应对传输中可能出现的中断、重复上传等问题,我们设计并实现了一套基于 ** Go 服务端 + S3 存储** 的文件上传机制。该方案支持** 断点续传** 与** 秒传** ,并具备良好的** 可扩展性** 和** 极简客户端 SDK** ,实现客户端与 S3 直连,** 数据流不经 API 服务中转** 。
1011
11- 在现代 App 或 Web 应用中,上传大文件已成为常见需求。为了应对大文件传输过程中的各种挑战,我们实现了一套基于 Go 服务端 + S3 存储的文件上传机制。该方案不仅支持断点续传和秒传,还支持服务器端扩展其他存储系统,同时保持 SDK 极简,客户端与存储系统直连,数据不经由 API 服务中转。
1212
13+ ## ✨ 设计目标
1314
14- ## 设计目标
1515
16+ - ✅ 极简 SDK:客户端无需存储系统适配逻辑
1617
17- - 减少 SDK 体积与复杂度
18+ - ✅ 降低服务器负载:文件流量不经由 API 服务
1819
19- - 降低服务端压力,文件流量不经过 API 服务
20+ - ✅ 支持断点续传与秒传,提升用户体验
2021
21- - 支持断点续传、秒传
22+ - ✅ 兼容任意 S3 接口,易于接入多种对象存储
2223
23- - 灵活支持多种 S3 兼容存储系统
24+ - ✅ 可拓展支持非 S3 的 HTTP PUT 分片上传
2425
25- - 可拓展支持非 S3 的 PUT 上传接口
2626
2727
28- ## 上传流程详解
28+ ## 📦 上传流程
2929
3030
31- 整个上传过程分为以下几个关键步骤 :
31+ 上传流程共分为五步 :
3232
33- 1 . 获取分片大小 ` /object/part_limit `
34- 客户端 SDK 会首次请求接口 ` /object/part_limit ` 获取服务器定义的分片大小(如 5MB),并将该值缓存。
3533
36- ### 2. 计算分片哈希与文件整体哈希
34+ ### 1. 获取分片大小
3735
36+ 接口:` GET /object/part_limit `
3837
39- 根据分片大小,客户端将文件切分为多个 part,并计算每一块的哈希值。随后,将所有分片哈希拼接,计算出文件的整体 hash(用于秒传检测) 。
38+ 客户端首次上传前,请求服务端获取推荐的分片大小(如 5MB),并进行缓存 。
4039
41- 3 . 初始化上传 ` /object/initiate_multipart_upload `
4240
43- - 客户端向服务端发起初始化上传请求。
41+ ### 2. 计算文件哈希
4442
45- - 若该文件已存在(通过 hash 匹配),服务端直接返回下载地址 。
43+ 客户端将文件按分片大小切分,并计算每个分片的哈希值。然后将所有分片哈希拼接,最终计算出文件整体哈希( ` file_hash ` ),用于秒传判断 。
4644
47- - 若文件不存在,返回每一分片所需的上传签名,包括分片的上传 URL、Header、编号等信息。
4845
46+ ### 3. 初始化上传
4947
50- ### 4. 上传分片(客户端直传 S3)
48+ 接口: ` POST /object/initiate_multipart_upload `
5149
50+ 客户端提交文件整体信息(如 hash、文件名、大小):
5251
53- 客户端使用签名信息,将分片通过 HTTP PUT 上传到指定的 S3 地址。上传过程中的每一块信息(如 ETag、PartNumber)被 SDK 记录本地,以支持断点续传。
5452
53+ - 若服务器发现该文件已存在(通过 ` file_hash ` 判断),则返回秒传成功的下载地址;
5554
55+ - 若不存在,则返回每个分片的上传签名信息,包括:
5656
57- > 上传和下载过程中文件流不经过 API 服务,均为客户端直连 S3。
5857
59- 5 . 完成上传 ` /object/complete_multipart_upload `
58+ - 分片上传 URL
6059
61- 当所有分片上传完毕后,SDK 调用接口通知服务端合并。
60+ - 必需的 Header(如 ` Content-Type ` , ` Authorization ` )
6261
63- 服务端校验所有块哈希与整体 hash,校验成功后通知 S3 合并,并返回最终文件的访问 URL。
62+ - ` PartNumber ` 等标识
6463
6564
66- ## 下载流程
65+ ### 4. 上传分片(直传 S3)
6766
68- 客户端通过从 API 获取的文件 URL 进行下载,该地址为临时的带签名的 S3 地址,可设置权限控制或时效性。
6967
70- ## 特别说明
68+ 客户端使用返回的签名信息,将每个分片通过 HTTP PUT 直接上传至 S3,对应:
7169
72- - 上传成功返回的 URL 为 API 地址,访问该地址会重定向到带签名的真实 S3 地址。你也可以在这一步加权限判断。
7370
74- - 所有文件上传和下载都不走 API 流量,仅用于控制和调度逻辑。
71+ - 上传过程中记录每一分片的 ETag 与 PartNumber
7572
76- ## 特性总结
73+ - SDK 持久化这些信息,实现断点续传
7774
7875
79- ### ✅ 支持秒传
8076
81- 文件 hash 校验可快速跳过上传过程 。
77+ > ⚠️ 文件内容始终不经由服务端,仅签名和元数据走 API 。
8278
83- ### ✅ 支持断点续传
8479
85- 客户端缓存上传信息,App 关闭后可继续上传。
80+ ### 5. 完成上传
8681
87- ### ✅ SDK 极简
82+ 接口: ` POST /object/complete_multipart_upload `
8883
89- SDK 不实现任何签名逻辑,所有签名由服务端统一生成。这样可支持任意 HTTP PUT 兼容的对象存储系统,而不需要修改客户端代码 。
84+ 客户端上传所有分片成功后,调用此接口提交分片信息列表 。
9085
91- ## 可扩展性
9286
93- 只要新的存储系统支持通过 HTTP PUT 上传分片,服务端即可为其实现签名生成逻辑,而无需更改客户端 SDK,这让整个系统拥有很高的可移植性。
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