Skip to content

Commit 14ef3f3

Browse files
committed
feat: file storage
1 parent 19c4cd3 commit 14ef3f3

1 file changed

Lines changed: 89 additions & 1 deletion

File tree

  • docs/blog/golang/architectural
Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,93 @@
11
---
2-
title: 文件断点续传的设计
2+
title: 文件存储
33
hide_title: true
44
sidebar_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,这让整个系统拥有很高的可移植性。

0 commit comments

Comments
 (0)