From bd7b0a71218ac9c6d41afcd7d07c476b3a9af52a Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Fri, 3 Jan 2025 12:11:34 +0800 Subject: [PATCH 1/7] feat: s3 convert --- docs/guides/solution/s3convert.mdx | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 docs/guides/solution/s3convert.mdx diff --git a/docs/guides/solution/s3convert.mdx b/docs/guides/solution/s3convert.mdx new file mode 100644 index 0000000000..1e794eb23c --- /dev/null +++ b/docs/guides/solution/s3convert.mdx @@ -0,0 +1,55 @@ +--- +title: '如何迁移到其他S3存储' +sidebar_position: 9 + +--- + +# S3存储接入 + +### 获取最新代码 +请下载项目的最新代码版本: + - 最新代码已集成`S3`迁移工具,无需单独操作。 +```shell +git clone https://github.com/openimsdk/open-im-server.git +cd open-im-server +``` + +### 配置文件修改指南 +请根据需要修改`config`目录下的相关配置文件,以完成迁移相关的 S3 配置: +1. 编辑`openim-rpc-third.yml`配置文件 + - 定位并更新与 S3 相关的配置项,确保其符合您的实际迁移需求。 +2. 关于 minio.yml 配置文件 + - 如果项目中未实际使用 MinIO,该文件可以忽略。 + - 如需使用,请同样根据迁移需求更新 S3 配置相关项。 +3. `openim-rpc-third.yml`中都有`object.enable`字段,用于指定新的S3存储引擎。 + +### 编译S3迁移工具 +1. 进入工具目录 +```shell +cd tools/s3 +``` +2. 执行编译命令 +```shell +go build -o s3convert main.go +``` + +### 开始迁移 +为确保数据迁移过程的稳定性,请按照以下建议进行操作: +1. 准备工作 + - 关闭服务:建议在服务停止的状态下进行迁移操作,以避免数据不一致或操作冲突。 + - 备份 MongoDB:重点备份`s3`表的数据,以便在发生意外时快速恢复。 +2. 迁移说明 + - 迁移工具不会删除原有的`S3`数据,但会修改`MongoDB`中`s3`表的相关记录。 + - 请在迁移完成后,核对数据完整性,确保所有迁移步骤正确执行。 +3. 执行迁移命令 + - ``:指定配置文件目录路径。 + - ``:填写原 S3 配置名称,例如 minio。 +```shell +./s3convert -config -name +``` +4. 示例命令 +如配置文件位于 config 目录下,且原 S3 名称为 minio,可执行以下命令: +```shell +./s3convert -config ./../../config -name minio +``` +当看到输出信息`success`时,表示迁移操作已完成。 \ No newline at end of file From c26ef568f3f03dfc600007912db02cbaa369ae00 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 9 Jan 2025 17:43:07 +0800 Subject: [PATCH 2/7] feat: add send_business_notification --- .../messageManagement/send_notification.mdx | 95 ++++++++++++++++++ .../messageManagement/send_notification.mdx | 97 +++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 docs/restapi/apis/messageManagement/send_notification.mdx create mode 100644 i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx diff --git a/docs/restapi/apis/messageManagement/send_notification.mdx b/docs/restapi/apis/messageManagement/send_notification.mdx new file mode 100644 index 0000000000..868c809e12 --- /dev/null +++ b/docs/restapi/apis/messageManagement/send_notification.mdx @@ -0,0 +1,95 @@ +--- +sidebar_position: 5 +title: 发送业务通知 +hide_title: true +--- + +
+ +## 发送业务通知 + +
+ +### 简要描述 +- 根据业务需要,发送通知消息。 +### 请求方式 +- `post` +### 请求URL +- `{API_ADDRESS}/msg/send_business_notification` + + +### Header +|header名|示例值|选填|类型|说明| +|:---- |:------- |:--- |---|------ | +|operationID|1646445464564|必填|string|用于全局链路追踪,建议使用时间戳,在每个请求中独立| +|token|eyJhbxxxx3Xs|必填|string|[管理员 token](docs/restapi/apis/authenticationManagement/getAdminToken.mdx)| + + +### 请求参数示例 + + +```json +{ + "sendUserID": "openIMAdmin", + "recvUserID": "2839678182", + "recvGroupID": "", + "key": "xxx", + "data": "xxxxxx", + "sendMsg": false, + "reliabilityLevel": 1 +} +``` +|字段名|选填|类型|说明| +|:---- |:------- |:--- |---| +|sendUserID|必填|string|系统通知号ID,或用户ID| +|recvUserID|选填|string|接收者用户ID,与`recvGroupID`只能选其中一个| +|recvGroupID|选填|string|接收群ID,与`recvUserID`只能选其中一个| +|key|必填|string|根据业务分类,客户端可以通过改字段用不同方法处理`data`| +|data|必填|string|业务数据| +|sendMsg|选填|bool|是否已消息形式发送,默认: false| +|reliabilityLevel|选填|int|通知消息的可靠基本,1: 在线推送。2: 必达通知(会在消息表中存储),默认: 1| +### 成功返回示例 + + +```json +{ + "errCode": 0, + "errMsg": "", + "errDlt": "", + "data": { + "serverMsgID": "8698dd5d163dd79b8fdfa333fee06f40", + "clientMsgID": "1ca0e4cf279ad5cce6b28331b2b42092", + "sendTime": 1679558586210 + } +} +``` +### 成功返回示例的参数说明 + + +|参数名|类型|说明| +|:---- |:------- |:--- | +|errCode|int|错误码,0表示成功| +|errMsg|string|错误简要信息,为空| +|errDlt|errDlt|错误详细信息,为空| +|data|object|通用数据对象,具体结构见下方| +|serverMsgID|string|服务器消息ID,预留字段| +|clientMsgID|string|客户端消息ID,此ID为消息唯一ID| +|sendTime|int|消息发送的时间| +### 失败返回示例 + + +```json +{ + "errCode": 1004, + "errMsg": "RecordNotFoundError", + "errDlt": ": [1004]RecordNotFoundError" +} +``` +### 失败返回示例的参数说明 + + +|参数名|类型|说明| +|:---- |:------- |:--- | +|errCode|int|错误码,具体查看全局错误码文档| +|errMsg|string|错误简要信息| +|errDlt|errDlt|错误详细信息| diff --git a/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx b/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx new file mode 100644 index 0000000000..c6833402ea --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx @@ -0,0 +1,97 @@ +--- +sidebar_position: 1 +title: send business notification +hide_title: true +--- + +
+ +## Send Business Notification + +
+ +### Brief Description +- Send notification messages according to business needs. + +### Request Method +- `post` + +### Request URL +- `{API_ADDRESS}/msg/send_business_notification` + +### Header + +| Header Name | Example Value | Optional | Type | Description | +|:------------|:----------------|:---------|:-------|:---------------------------------------------------------------------------| +| operationID | 1646445464564 | Required | string | Used for global trace tracking; suggested to use a unique timestamp per request | +| token | eyJhbxxxx3Xs | Required | string | [Admin token](/restapi/apis/authenticationManagement/getAdminToken) | + +### Request Parameters Example + +```json +{ + "sendUserID": "openIMAdmin", + "recvUserID": "2839678182", + "recvGroupID": "", + "key": "xxx", + "data": "xxxxxx", + "sendMsg": false, + "reliabilityLevel": 1 +} +``` + +| Field Name | Optional | Type | Description | +|:-----------------------|:---------|:---------|:----------------------------------------------------------------------------| +| sendUserID | Required | string | System notification ID, or user ID | +| recvUserID | Optional | string | Receiver user ID, can only choose one from `recvGroupID` | +|recvGroupID| Optional |string|Receive group ID, you can only choose one from `recvUserID`| +|key| Required |string|Depending on the business classification, the client can process `data` in different ways by changing the field| +|data| Required |string|Business data| +|sendMsg| Optional |bool|Whether to send as a message, default: false| +|reliabilityLevel| Optional |int|The reliability of notification messages, 1: online push. 2: must-have notification (will be stored in the message table), default: 1| + + +### Success Response Example + +```json +{ + "errCode": 0, + "errMsg": "", + "errDlt": "", + "data": { + "serverMsgID": "8698dd5d163dd79b8fdfa333fee06f40", + "clientMsgID": "1ca0e4cf279ad5cce6b28331b2b42092", + "sendTime": 1679558586210 + } +} +``` + +### Success Response Parameters Description + +| Parameter Name | Type | Description | +|:---------------|:-------|:----------------------------------------| +| errCode | int | Error code; 0 indicates success | +| errMsg | string | Brief error message, empty if none | +| errDlt | errDlt | Detailed error information, empty if none | +| data | object | General data object, structure detailed below | +| serverMsgID | string | Server message ID; reserved field | +| clientMsgID | string | Client message ID; unique ID for message | +| sendTime | int | Time the message was sent | + +### Failure Response Example + +```json +{ + "errCode": 1004, + "errMsg": "RecordNotFoundError", + "errDlt": ": [1004]RecordNotFoundError" +} +``` + +### Failure Response Parameters Description + +| Parameter Name | Type | Description | +|:---------------|:-------|:------------------------------------------------| +| errCode | int | Error code, refer to global error code documentation | +| errMsg | string | Brief error message | +| errDlt | errDlt | Detailed error information | From 8b075e2aa6759342faa7400bbcfe009de1007e0f Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 9 Jan 2025 17:44:59 +0800 Subject: [PATCH 3/7] feat: add send_business_notification --- .../{send_notification.mdx => send_business_notification.mdx} | 0 .../{send_notification.mdx => send_business_notification.mdx} | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/restapi/apis/messageManagement/{send_notification.mdx => send_business_notification.mdx} (100%) rename i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/{send_notification.mdx => send_business_notification.mdx} (98%) diff --git a/docs/restapi/apis/messageManagement/send_notification.mdx b/docs/restapi/apis/messageManagement/send_business_notification.mdx similarity index 100% rename from docs/restapi/apis/messageManagement/send_notification.mdx rename to docs/restapi/apis/messageManagement/send_business_notification.mdx diff --git a/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx b/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx similarity index 98% rename from i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx rename to i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx index c6833402ea..ad3c03ab9a 100644 --- a/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_notification.mdx +++ b/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx @@ -1,6 +1,6 @@ --- -sidebar_position: 1 -title: send business notification +sidebar_position: 5 +title: Send Business Notification hide_title: true --- From ca5f7f9f65978b64082df559183d678ff0c4c0f7 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 9 Jan 2025 17:54:41 +0800 Subject: [PATCH 4/7] feat: add send_business_notification --- .../apis/messageManagement/send_business_notification.mdx | 4 ++-- .../apis/messageManagement/send_business_notification.mdx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/restapi/apis/messageManagement/send_business_notification.mdx b/docs/restapi/apis/messageManagement/send_business_notification.mdx index 868c809e12..a4150f089c 100644 --- a/docs/restapi/apis/messageManagement/send_business_notification.mdx +++ b/docs/restapi/apis/messageManagement/send_business_notification.mdx @@ -11,7 +11,7 @@ hide_title: true ### 简要描述 -- 根据业务需要,发送通知消息。 +- 业务服务发送自定义通知,客户端会收到OnRecvCustomBusinessMessage回调 ### 请求方式 - `post` ### 请求URL @@ -47,7 +47,7 @@ hide_title: true |key|必填|string|根据业务分类,客户端可以通过改字段用不同方法处理`data`| |data|必填|string|业务数据| |sendMsg|选填|bool|是否已消息形式发送,默认: false| -|reliabilityLevel|选填|int|通知消息的可靠基本,1: 在线推送。2: 必达通知(会在消息表中存储),默认: 1| +|reliabilityLevel|选填|int|通知消息的可靠基本,1: 在线推送。2: 必达通知(断线重连或重新登录也会触发,用于必达的场景,该可靠性等级下,由于是顺序全量同步,建议不能发送过多,否则会影响客户端消息同步性能),默认: 1| ### 成功返回示例 diff --git a/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx b/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx index ad3c03ab9a..799da28868 100644 --- a/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx +++ b/i18n/en/docusaurus-plugin-content-docs-restapi/current/apis/messageManagement/send_business_notification.mdx @@ -11,7 +11,7 @@ hide_title: true ### Brief Description -- Send notification messages according to business needs. +- The business service sends a custom notification, and the client receives the OnRecvCustomBusinessMessage callback ### Request Method - `post` @@ -48,7 +48,7 @@ hide_title: true |key| Required |string|Depending on the business classification, the client can process `data` in different ways by changing the field| |data| Required |string|Business data| |sendMsg| Optional |bool|Whether to send as a message, default: false| -|reliabilityLevel| Optional |int|The reliability of notification messages, 1: online push. 2: must-have notification (will be stored in the message table), default: 1| +|reliabilityLevel| Optional |int|The reliability of notification messages is as follows: 1: Online push. 2: Must-reach notification (will also be triggered by disconnection and reconnection or re-login, used for scenarios where must-reach notifications are required. At this reliability level, since it is a sequential full synchronization, it is recommended not to send too many messages, otherwise it will affect the client message synchronization performance). Default: 1| ### Success Response Example From 14ef3f31a6cf1a21293df422f71075e6ea85def0 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Wed, 7 May 2025 15:52:19 +0800 Subject: [PATCH 5/7] feat: file storage --- docs/blog/golang/architectural/3.mdx | 90 +++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/docs/blog/golang/architectural/3.mdx b/docs/blog/golang/architectural/3.mdx index 64dc2f7c52..10862f854f 100644 --- a/docs/blog/golang/architectural/3.mdx +++ b/docs/blog/golang/architectural/3.mdx @@ -1,5 +1,93 @@ --- -title: 文件断点续传的设计 +title: 文件存储 hide_title: true sidebar_position: 3 --- + + +# 基于 Go 与 S3 的高效文件上传实现:支持断点续传与秒传 + + +在现代 App 或 Web 应用中,上传大文件已成为常见需求。为了应对大文件传输过程中的各种挑战,我们实现了一套基于 Go 服务端 + S3 存储的文件上传机制。该方案不仅支持断点续传和秒传,还支持服务器端扩展其他存储系统,同时保持 SDK 极简,客户端与存储系统直连,数据不经由 API 服务中转。 + + +## 设计目标 + + +- 减少 SDK 体积与复杂度 + +- 降低服务端压力,文件流量不经过 API 服务 + +- 支持断点续传、秒传 + +- 灵活支持多种 S3 兼容存储系统 + +- 可拓展支持非 S3 的 PUT 上传接口 + + +## 上传流程详解 + + +整个上传过程分为以下几个关键步骤: + +1. 获取分片大小 `/object/part_limit` +客户端 SDK 会首次请求接口 `/object/part_limit` 获取服务器定义的分片大小(如 5MB),并将该值缓存。 + +### 2. 计算分片哈希与文件整体哈希 + + +根据分片大小,客户端将文件切分为多个 part,并计算每一块的哈希值。随后,将所有分片哈希拼接,计算出文件的整体 hash(用于秒传检测)。 + +3. 初始化上传 `/object/initiate_multipart_upload` + +- 客户端向服务端发起初始化上传请求。 + +- 若该文件已存在(通过 hash 匹配),服务端直接返回下载地址。 + +- 若文件不存在,返回每一分片所需的上传签名,包括分片的上传 URL、Header、编号等信息。 + + +### 4. 上传分片(客户端直传 S3) + + +客户端使用签名信息,将分片通过 HTTP PUT 上传到指定的 S3 地址。上传过程中的每一块信息(如 ETag、PartNumber)被 SDK 记录本地,以支持断点续传。 + + + +> 上传和下载过程中文件流不经过 API 服务,均为客户端直连 S3。 + +5. 完成上传 `/object/complete_multipart_upload` + +当所有分片上传完毕后,SDK 调用接口通知服务端合并。 + +服务端校验所有块哈希与整体 hash,校验成功后通知 S3 合并,并返回最终文件的访问 URL。 + + +## 下载流程 + +客户端通过从 API 获取的文件 URL 进行下载,该地址为临时的带签名的 S3 地址,可设置权限控制或时效性。 + +## 特别说明 + +- 上传成功返回的 URL 为 API 地址,访问该地址会重定向到带签名的真实 S3 地址。你也可以在这一步加权限判断。 + +- 所有文件上传和下载都不走 API 流量,仅用于控制和调度逻辑。 + +## 特性总结 + + +### ✅ 支持秒传 + +文件 hash 校验可快速跳过上传过程。 + +### ✅ 支持断点续传 + +客户端缓存上传信息,App 关闭后可继续上传。 + +### ✅ SDK 极简 + +SDK 不实现任何签名逻辑,所有签名由服务端统一生成。这样可支持任意 HTTP PUT 兼容的对象存储系统,而不需要修改客户端代码。 + +## 可扩展性 + +只要新的存储系统支持通过 HTTP PUT 上传分片,服务端即可为其实现签名生成逻辑,而无需更改客户端 SDK,这让整个系统拥有很高的可移植性。 From 2a2127024d0ad5b5f2bb6fd3f90e954b46c96f3a Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Wed, 7 May 2025 17:20:54 +0800 Subject: [PATCH 6/7] feat: file storage --- docs/blog/golang/architectural/3.mdx | 107 +++++++++++++++++---------- 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/docs/blog/golang/architectural/3.mdx b/docs/blog/golang/architectural/3.mdx index 10862f854f..ce55d86889 100644 --- a/docs/blog/golang/architectural/3.mdx +++ b/docs/blog/golang/architectural/3.mdx @@ -5,89 +5,120 @@ sidebar_position: 3 --- -# 基于 Go 与 S3 的高效文件上传实现:支持断点续传与秒传 +# 基于 Go 与 S3 的高效大文件上传方案 —— 支持断点续传与秒传 +在现代 App 与 Web 应用中,大文件上传是常见且关键的功能。为应对传输中可能出现的中断、重复上传等问题,我们设计并实现了一套基于 **Go 服务端 + S3 存储** 的文件上传机制。该方案支持**断点续传** 与**秒传** ,并具备良好的**可扩展性** 和**极简客户端 SDK** ,实现客户端与 S3 直连,**数据流不经 API 服务中转** 。 -在现代 App 或 Web 应用中,上传大文件已成为常见需求。为了应对大文件传输过程中的各种挑战,我们实现了一套基于 Go 服务端 + S3 存储的文件上传机制。该方案不仅支持断点续传和秒传,还支持服务器端扩展其他存储系统,同时保持 SDK 极简,客户端与存储系统直连,数据不经由 API 服务中转。 +## ✨ 设计目标 -## 设计目标 +- ✅ 极简 SDK:客户端无需存储系统适配逻辑 -- 减少 SDK 体积与复杂度 +- ✅ 降低服务器负载:文件流量不经由 API 服务 -- 降低服务端压力,文件流量不经过 API 服务 +- ✅ 支持断点续传与秒传,提升用户体验 -- 支持断点续传、秒传 +- ✅ 兼容任意 S3 接口,易于接入多种对象存储 -- 灵活支持多种 S3 兼容存储系统 +- ✅ 可拓展支持非 S3 的 HTTP PUT 分片上传 -- 可拓展支持非 S3 的 PUT 上传接口 -## 上传流程详解 +## 📦 上传流程 -整个上传过程分为以下几个关键步骤: +上传流程共分为五步: -1. 获取分片大小 `/object/part_limit` -客户端 SDK 会首次请求接口 `/object/part_limit` 获取服务器定义的分片大小(如 5MB),并将该值缓存。 -### 2. 计算分片哈希与文件整体哈希 +### 1. 获取分片大小 +接口:`GET /object/part_limit` -根据分片大小,客户端将文件切分为多个 part,并计算每一块的哈希值。随后,将所有分片哈希拼接,计算出文件的整体 hash(用于秒传检测)。 +客户端首次上传前,请求服务端获取推荐的分片大小(如 5MB),并进行缓存。 -3. 初始化上传 `/object/initiate_multipart_upload` -- 客户端向服务端发起初始化上传请求。 +### 2. 计算文件哈希 -- 若该文件已存在(通过 hash 匹配),服务端直接返回下载地址。 +客户端将文件按分片大小切分,并计算每个分片的哈希值。然后将所有分片哈希拼接,最终计算出文件整体哈希(`file_hash`),用于秒传判断。 -- 若文件不存在,返回每一分片所需的上传签名,包括分片的上传 URL、Header、编号等信息。 +### 3. 初始化上传 -### 4. 上传分片(客户端直传 S3) +接口:`POST /object/initiate_multipart_upload` +客户端提交文件整体信息(如 hash、文件名、大小): -客户端使用签名信息,将分片通过 HTTP PUT 上传到指定的 S3 地址。上传过程中的每一块信息(如 ETag、PartNumber)被 SDK 记录本地,以支持断点续传。 +- 若服务器发现该文件已存在(通过 `file_hash` 判断),则返回秒传成功的下载地址; +- 若不存在,则返回每个分片的上传签名信息,包括: -> 上传和下载过程中文件流不经过 API 服务,均为客户端直连 S3。 -5. 完成上传 `/object/complete_multipart_upload` + - 分片上传 URL -当所有分片上传完毕后,SDK 调用接口通知服务端合并。 + - 必需的 Header(如 `Content-Type`, `Authorization`) -服务端校验所有块哈希与整体 hash,校验成功后通知 S3 合并,并返回最终文件的访问 URL。 + - `PartNumber` 等标识 -## 下载流程 +### 4. 上传分片(直传 S3) -客户端通过从 API 获取的文件 URL 进行下载,该地址为临时的带签名的 S3 地址,可设置权限控制或时效性。 -## 特别说明 +客户端使用返回的签名信息,将每个分片通过 HTTP PUT 直接上传至 S3,对应: -- 上传成功返回的 URL 为 API 地址,访问该地址会重定向到带签名的真实 S3 地址。你也可以在这一步加权限判断。 -- 所有文件上传和下载都不走 API 流量,仅用于控制和调度逻辑。 +- 上传过程中记录每一分片的 ETag 与 PartNumber -## 特性总结 +- SDK 持久化这些信息,实现断点续传 -### ✅ 支持秒传 -文件 hash 校验可快速跳过上传过程。 +> ⚠️ 文件内容始终不经由服务端,仅签名和元数据走 API。 -### ✅ 支持断点续传 -客户端缓存上传信息,App 关闭后可继续上传。 +### 5. 完成上传 -### ✅ SDK 极简 +接口:`POST /object/complete_multipart_upload` -SDK 不实现任何签名逻辑,所有签名由服务端统一生成。这样可支持任意 HTTP PUT 兼容的对象存储系统,而不需要修改客户端代码。 +客户端上传所有分片成功后,调用此接口提交分片信息列表。 -## 可扩展性 -只要新的存储系统支持通过 HTTP PUT 上传分片,服务端即可为其实现签名生成逻辑,而无需更改客户端 SDK,这让整个系统拥有很高的可移植性。 +- 服务端校验每个分片哈希及整体 hash + +- 校验通过后,发起 S3 的合并操作 + +- 最终返回文件的访问地址(可跳转到签名 S3 URL) + + +## ⬇️ 下载流程 + + +客户端下载时,从服务端获取临时签名下载地址(S3 Pre-signed URL),可设置权限与有效期控制。该地址可通过 API 统一跳转实现权限校验。 + + + +## ✅ 特性一览 + +| 特性 | 说明 | +| --- | --- | +| 秒传支持 | 基于文件 hash 实现上传秒跳过 | +| 断点续传 | 支持断线、异常退出后继续上传 | +| 极简 SDK | 客户端无需签名逻辑,仅执行 PUT | +| 存储兼容性强 | 支持任意兼容 HTTP PUT 的对象存储 | +| 高可拓展性 | 可快速接入其他上传协议和存储系统 | + + + +## ⚙️ 可扩展性设计 + + +该方案以“服务端统一生成签名 + 客户端通用 PUT 上传”为核心架构,只要目标存储系统支持分片上传并接受带签名的 PUT 请求,即可无缝接入: + + +- 支持 Amazon S3、MinIO、阿里云 OSS、腾讯云 COS 等 + +- 也可扩展支持其它上传服务 + + +客户端代码不变,服务端扩展签名生成逻辑即可。 From 1e6b4077b7885add2debafae684e21e5c4bf9394 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Wed, 7 May 2025 17:21:39 +0800 Subject: [PATCH 7/7] feat: file storage --- docs/blog/golang/architectural/3.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/blog/golang/architectural/3.mdx b/docs/blog/golang/architectural/3.mdx index ce55d86889..ab259dad02 100644 --- a/docs/blog/golang/architectural/3.mdx +++ b/docs/blog/golang/architectural/3.mdx @@ -5,9 +5,9 @@ sidebar_position: 3 --- -# 基于 Go 与 S3 的高效大文件上传方案 —— 支持断点续传与秒传 +# 基于 Go 与 S3 的高效文件上传方案 —— 支持断点续传与秒传 -在现代 App 与 Web 应用中,大文件上传是常见且关键的功能。为应对传输中可能出现的中断、重复上传等问题,我们设计并实现了一套基于 **Go 服务端 + S3 存储** 的文件上传机制。该方案支持**断点续传** 与**秒传** ,并具备良好的**可扩展性** 和**极简客户端 SDK** ,实现客户端与 S3 直连,**数据流不经 API 服务中转** 。 +在现代 App 与 Web 应用中,文件上传是常见且关键的功能。为应对传输中可能出现的中断、重复上传等问题,我们设计并实现了一套基于 **Go 服务端 + S3 存储** 的文件上传机制。该方案支持**断点续传** 与**秒传** ,并具备良好的**可扩展性** 和**极简客户端 SDK** ,实现客户端与 S3 直连,**数据流不经 API 服务中转** 。 ## ✨ 设计目标