File tree Expand file tree Collapse file tree
docs/blog/golang/architectural Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11---
2- title : 文件断点续传的设计
2+ title : 文件存储
33hide_title : true
44sidebar_position : 3
55---
6+
7+
8+ # 基于 Go 与 S3 的高效文件上传实现:支持断点续传与秒传
9+
10+
11+ 在现代 App 或 Web 应用中,上传大文件已成为常见需求。为了应对大文件传输过程中的各种挑战,我们实现了一套基于 Go 服务端 + S3 存储的文件上传机制。该方案不仅支持断点续传和秒传,还支持服务器端扩展其他存储系统,同时保持 SDK 极简,客户端与存储系统直连,数据不经由 API 服务中转。
12+
13+
14+ ## 设计目标
15+
16+
17+ - 减少 SDK 体积与复杂度
18+
19+ - 降低服务端压力,文件流量不经过 API 服务
20+
21+ - 支持断点续传、秒传
22+
23+ - 灵活支持多种 S3 兼容存储系统
24+
25+ - 可拓展支持非 S3 的 PUT 上传接口
26+
27+
28+ ## 上传流程详解
29+
30+
31+ 整个上传过程分为以下几个关键步骤:
32+
33+ 1 . 获取分片大小 ` /object/part_limit `
34+ 客户端 SDK 会首次请求接口 ` /object/part_limit ` 获取服务器定义的分片大小(如 5MB),并将该值缓存。
35+
36+ ### 2. 计算分片哈希与文件整体哈希
37+
38+
39+ 根据分片大小,客户端将文件切分为多个 part,并计算每一块的哈希值。随后,将所有分片哈希拼接,计算出文件的整体 hash(用于秒传检测)。
40+
41+ 3 . 初始化上传 ` /object/initiate_multipart_upload `
42+
43+ - 客户端向服务端发起初始化上传请求。
44+
45+ - 若该文件已存在(通过 hash 匹配),服务端直接返回下载地址。
46+
47+ - 若文件不存在,返回每一分片所需的上传签名,包括分片的上传 URL、Header、编号等信息。
48+
49+
50+ ### 4. 上传分片(客户端直传 S3)
51+
52+
53+ 客户端使用签名信息,将分片通过 HTTP PUT 上传到指定的 S3 地址。上传过程中的每一块信息(如 ETag、PartNumber)被 SDK 记录本地,以支持断点续传。
54+
55+
56+
57+ > 上传和下载过程中文件流不经过 API 服务,均为客户端直连 S3。
58+
59+ 5 . 完成上传 ` /object/complete_multipart_upload `
60+
61+ 当所有分片上传完毕后,SDK 调用接口通知服务端合并。
62+
63+ 服务端校验所有块哈希与整体 hash,校验成功后通知 S3 合并,并返回最终文件的访问 URL。
64+
65+
66+ ## 下载流程
67+
68+ 客户端通过从 API 获取的文件 URL 进行下载,该地址为临时的带签名的 S3 地址,可设置权限控制或时效性。
69+
70+ ## 特别说明
71+
72+ - 上传成功返回的 URL 为 API 地址,访问该地址会重定向到带签名的真实 S3 地址。你也可以在这一步加权限判断。
73+
74+ - 所有文件上传和下载都不走 API 流量,仅用于控制和调度逻辑。
75+
76+ ## 特性总结
77+
78+
79+ ### ✅ 支持秒传
80+
81+ 文件 hash 校验可快速跳过上传过程。
82+
83+ ### ✅ 支持断点续传
84+
85+ 客户端缓存上传信息,App 关闭后可继续上传。
86+
87+ ### ✅ SDK 极简
88+
89+ SDK 不实现任何签名逻辑,所有签名由服务端统一生成。这样可支持任意 HTTP PUT 兼容的对象存储系统,而不需要修改客户端代码。
90+
91+ ## 可扩展性
92+
93+ 只要新的存储系统支持通过 HTTP PUT 上传分片,服务端即可为其实现签名生成逻辑,而无需更改客户端 SDK,这让整个系统拥有很高的可移植性。
You can’t perform that action at this time.
0 commit comments