305 lines
13 KiB
Markdown
305 lines
13 KiB
Markdown
|
|
# 对象存储配置
|
|||
|
|
|
|||
|
|
<cite>
|
|||
|
|
**本文引用的文件列表**
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go)
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go)
|
|||
|
|
- [cmd/server/main.go](file://cmd/server/main.go)
|
|||
|
|
- [start.sh](file://start.sh)
|
|||
|
|
</cite>
|
|||
|
|
|
|||
|
|
## 目录
|
|||
|
|
1. [简介](#简介)
|
|||
|
|
2. [项目结构](#项目结构)
|
|||
|
|
3. [核心组件](#核心组件)
|
|||
|
|
4. [架构总览](#架构总览)
|
|||
|
|
5. [详细组件分析](#详细组件分析)
|
|||
|
|
6. [依赖关系分析](#依赖关系分析)
|
|||
|
|
7. [性能考量](#性能考量)
|
|||
|
|
8. [故障排查指南](#故障排查指南)
|
|||
|
|
9. [结论](#结论)
|
|||
|
|
10. [附录](#附录)
|
|||
|
|
|
|||
|
|
## 简介
|
|||
|
|
本文件面向开发者,系统性说明 CarrotSkin 项目与 RustFS(S3 兼容)对象存储的集成配置。重点涵盖以下方面:
|
|||
|
|
- 核心配置项 rustfs.endpoint、access_key、secret_key、use_ssl 的作用与含义
|
|||
|
|
- 存储桶配置 buckets 的动态加载机制,以及通过 RUSTFS_BUCKET_TEXTURES 和 RUSTFS_BUCKET_AVATARS 环境变量为不同用途(材质与头像)设置存储桶
|
|||
|
|
- 基于 RustFSConfig 结构体的安全配置最佳实践,包括凭证管理与 SSL 配置建议
|
|||
|
|
|
|||
|
|
## 项目结构
|
|||
|
|
CarrotSkin 的对象存储配置由“配置层 → 存储层 → 业务层”三层协作完成:
|
|||
|
|
- 配置层:负责从环境变量加载并合并 RustFSConfig,支持运行时覆盖
|
|||
|
|
- 存储层:封装 S3 兼容客户端(minio-go),提供桶名映射与预签名上传能力
|
|||
|
|
- 业务层:根据文件类型生成上传 URL,按需选择对应存储桶
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph TB
|
|||
|
|
subgraph "配置层"
|
|||
|
|
CFG["RustFSConfig<br/>endpoint/access_key/secret_key/use_ssl/buckets"]
|
|||
|
|
CMGR["配置管理器<br/>Init/GetRustFSConfig"]
|
|||
|
|
end
|
|||
|
|
subgraph "存储层"
|
|||
|
|
SMGR["存储管理器<br/>Init/GetClient"]
|
|||
|
|
SCLI["StorageClient<br/>minio.Client + buckets 映射"]
|
|||
|
|
end
|
|||
|
|
subgraph "业务层"
|
|||
|
|
SVC["上传服务<br/>生成头像/材质上传URL"]
|
|||
|
|
end
|
|||
|
|
CMGR --> CFG
|
|||
|
|
SMGR --> SCLI
|
|||
|
|
SVC --> SCLI
|
|||
|
|
CFG --> SMGR
|
|||
|
|
SCLI --> SVC
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L58-L66)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L18-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L121)
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L78-L160)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L58-L66)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L18-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L121)
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L78-L160)
|
|||
|
|
- [cmd/server/main.go](file://cmd/server/main.go#L63-L69)
|
|||
|
|
|
|||
|
|
## 核心组件
|
|||
|
|
- RustFSConfig:定义对象存储的端点、凭证、协议开关与桶映射
|
|||
|
|
- 配置管理器:提供全局单例的配置加载与获取能力
|
|||
|
|
- 存储管理器:提供全局单例的存储客户端初始化与获取能力
|
|||
|
|
- StorageClient:封装 minio-go 客户端,提供桶名映射与预签名上传能力
|
|||
|
|
- 上传服务:按文件类型生成预签名上传 URL,并选择对应存储桶
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L58-L66)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L18-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L121)
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L78-L160)
|
|||
|
|
|
|||
|
|
## 架构总览
|
|||
|
|
下图展示从应用启动到生成上传 URL 的关键流程,以及各组件之间的依赖关系。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Main as "主程序"
|
|||
|
|
participant CfgMgr as "配置管理器"
|
|||
|
|
participant Cfg as "RustFSConfig"
|
|||
|
|
participant StorMgr as "存储管理器"
|
|||
|
|
participant StorCli as "StorageClient"
|
|||
|
|
participant Svc as "上传服务"
|
|||
|
|
Main->>CfgMgr : 调用 Init()
|
|||
|
|
CfgMgr->>CfgMgr : 加载环境变量并合并默认值
|
|||
|
|
CfgMgr-->>Main : 返回全局 RustFSConfig
|
|||
|
|
Main->>StorMgr : 调用 Init(RustFSConfig)
|
|||
|
|
StorMgr->>StorCli : NewStorage(cfg)
|
|||
|
|
StorCli-->>StorMgr : 返回 StorageClient
|
|||
|
|
StorMgr-->>Main : 初始化完成
|
|||
|
|
Svc->>StorCli : GetBucket("avatars"/"textures")
|
|||
|
|
Svc->>StorCli : GeneratePresignedPostURL(...)
|
|||
|
|
StorCli-->>Svc : 返回 PostURL + FormData + FileURL
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [cmd/server/main.go](file://cmd/server/main.go#L27-L70)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L18-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L121)
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L78-L160)
|
|||
|
|
|
|||
|
|
## 详细组件分析
|
|||
|
|
|
|||
|
|
### RustFSConfig 结构体与配置项说明
|
|||
|
|
- endpoint:RustFS 服务地址(含端口)。用于构建预签名上传 URL 的最终访问地址与协议选择
|
|||
|
|
- access_key / secret_key:访问凭证,用于构造静态凭据并建立 S3 兼容客户端
|
|||
|
|
- use_ssl:是否启用 HTTPS 协议;影响预签名上传 URL 的协议与文件访问 URL 的协议
|
|||
|
|
- buckets:存储桶映射,键为用途标识(如 "textures"、"avatars"),值为实际桶名
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L58-L66)
|
|||
|
|
|
|||
|
|
### 配置加载与动态覆盖
|
|||
|
|
- 默认值:通过 viper 设置默认值,包含 endpoint 与 use_ssl 的默认值
|
|||
|
|
- 环境变量映射:将 CARROTSKIN 前缀的环境变量绑定到配置键
|
|||
|
|
- 动态覆盖:overrideFromEnv 支持通过 RUSTFS_BUCKET_TEXTURES 与 RUSTFS_BUCKET_AVATARS 动态注入存储桶映射,无需修改配置文件
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L190-L236)
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L238-L253)
|
|||
|
|
|
|||
|
|
### 存储客户端初始化与连接测试
|
|||
|
|
- 客户端创建:基于 endpoint、access_key、secret_key、use_ssl 构造 minio-go 客户端
|
|||
|
|
- 连接测试:当凭证非空时,尝试列举桶以验证连通性
|
|||
|
|
- 桶映射:将 RustFSConfig 中的 buckets 直接注入 StorageClient
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L49)
|
|||
|
|
|
|||
|
|
### 存储桶映射与上传 URL 生成
|
|||
|
|
- GetBucket:按用途键("textures" 或 "avatars")从映射中取桶名
|
|||
|
|
- 预签名上传:根据文件类型与大小范围生成 POST 策略,返回 PostURL、FormData 与最终 FileURL
|
|||
|
|
- 协议选择:根据 use_ssl 决定协议(http/https)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L57-L121)
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L78-L160)
|
|||
|
|
|
|||
|
|
### 业务层调用链(头像上传)
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Svc as "上传服务"
|
|||
|
|
participant StorCli as "StorageClient"
|
|||
|
|
participant Cfg as "RustFSConfig"
|
|||
|
|
Svc->>Svc : 校验文件名与扩展名
|
|||
|
|
Svc->>StorCli : GetBucket("avatars")
|
|||
|
|
StorCli-->>Svc : 返回桶名
|
|||
|
|
Svc->>StorCli : GeneratePresignedPostURL(bucket, objectName, min/max/expire, useSSL, endpoint)
|
|||
|
|
StorCli-->>Svc : 返回 PostURL + FormData + FileURL
|
|||
|
|
Svc-->>Svc : 组装响应并返回
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L78-L115)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L82-L121)
|
|||
|
|
|
|||
|
|
### 业务层调用链(材质上传)
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Svc as "上传服务"
|
|||
|
|
participant StorCli as "StorageClient"
|
|||
|
|
participant Cfg as "RustFSConfig"
|
|||
|
|
Svc->>Svc : 校验文件名与扩展名
|
|||
|
|
Svc->>Svc : 校验材质类型(SKIN/CAPE)
|
|||
|
|
Svc->>StorCli : GetBucket("textures")
|
|||
|
|
StorCli-->>Svc : 返回桶名
|
|||
|
|
Svc->>StorCli : GeneratePresignedPostURL(...)
|
|||
|
|
StorCli-->>Svc : 返回 PostURL + FormData + FileURL
|
|||
|
|
Svc-->>Svc : 组装响应并返回
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [internal/service/upload_service.go](file://internal/service/upload_service.go#L117-L160)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L82-L121)
|
|||
|
|
|
|||
|
|
### 存储桶动态加载机制
|
|||
|
|
- 环境变量注入:RUSTFS_BUCKET_TEXTURES 与 RUSTFS_BUCKET_AVATARS 分别为“材质”和“头像”用途注入桶名
|
|||
|
|
- 映射合并:overrideFromEnv 在 RustFS.Buckets 为空时创建映射,再写入对应键值
|
|||
|
|
- 无配置文件依赖:完全通过环境变量驱动,便于容器化部署与多环境切换
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
flowchart TD
|
|||
|
|
Start(["启动"]) --> LoadEnv["加载环境变量"]
|
|||
|
|
LoadEnv --> Override["overrideFromEnv 动态覆盖"]
|
|||
|
|
Override --> CheckTextures{"RUSTFS_BUCKET_TEXTURES 是否存在"}
|
|||
|
|
CheckTextures --> |是| PutTextures["写入 buckets['textures']"]
|
|||
|
|
CheckTextures --> |否| Next1["跳过"]
|
|||
|
|
PutTextures --> Next2["继续检查"]
|
|||
|
|
Next1 --> Next2
|
|||
|
|
Next2 --> CheckAvatars{"RUSTFS_BUCKET_AVATARS 是否存在"}
|
|||
|
|
CheckAvatars --> |是| PutAvatars["写入 buckets['avatars']"]
|
|||
|
|
CheckAvatars --> |否| End(["结束"])
|
|||
|
|
PutAvatars --> End
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L238-L253)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L238-L253)
|
|||
|
|
|
|||
|
|
## 依赖关系分析
|
|||
|
|
- 配置层依赖 viper 与 godotenv,负责环境变量加载与默认值设置
|
|||
|
|
- 存储层依赖 minio-go,封装客户端与桶映射
|
|||
|
|
- 业务层依赖存储层提供的预签名上传能力
|
|||
|
|
- 启动流程在 main 中依次初始化配置、日志、数据库、JWT、Redis、对象存储与邮件服务
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph LR
|
|||
|
|
Viper["viper/godotenv"] --> Config["RustFSConfig"]
|
|||
|
|
Config --> Manager["配置管理器"]
|
|||
|
|
Manager --> StorageMgr["存储管理器"]
|
|||
|
|
StorageMgr --> StorageClient["StorageClient(minio-go)"]
|
|||
|
|
StorageClient --> UploadSvc["上传服务"]
|
|||
|
|
Main["main"] --> Manager
|
|||
|
|
Main --> StorageMgr
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L18-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L121)
|
|||
|
|
- [cmd/server/main.go](file://cmd/server/main.go#L27-L70)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L18-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L121)
|
|||
|
|
- [cmd/server/main.go](file://cmd/server/main.go#L27-L70)
|
|||
|
|
|
|||
|
|
## 性能考量
|
|||
|
|
- 预签名上传避免了服务端中转,降低带宽与延迟
|
|||
|
|
- 上传 URL 过期时间短(默认 15 分钟),减少凭证暴露风险
|
|||
|
|
- 桶映射为内存查找,开销极低
|
|||
|
|
- 连接测试仅在凭证非空时进行,避免不必要的网络往返
|
|||
|
|
|
|||
|
|
[本节为通用指导,不涉及具体文件分析]
|
|||
|
|
|
|||
|
|
## 故障排查指南
|
|||
|
|
- 配置未初始化
|
|||
|
|
- 现象:调用 GetRustFSConfig/MustGetRustFSConfig 或 GetClient/MustGetClient 报错
|
|||
|
|
- 排查:确认已在 main 中调用 config.Init() 与 storage.Init()
|
|||
|
|
- 凭证为空导致连接测试跳过
|
|||
|
|
- 现象:NewStorage 成功但未进行 ListBuckets 测试
|
|||
|
|
- 排查:若需验证连通性,请提供 access_key 与 secret_key
|
|||
|
|
- 存储桶不存在
|
|||
|
|
- 现象:GetBucket 返回错误
|
|||
|
|
- 排查:确认 RUSTFS_BUCKET_TEXTURES/RUSTFS_BUCKET_AVATARS 已正确设置,且与 RustFS 实际桶名一致
|
|||
|
|
- 预签名上传失败
|
|||
|
|
- 现象:GeneratePresignedPostURL 返回错误
|
|||
|
|
- 排查:检查 min/max 大小范围、过期时间、use_ssl 与 endpoint 是否匹配
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/manager.go](file://pkg/config/manager.go#L31-L63)
|
|||
|
|
- [pkg/storage/manager.go](file://pkg/storage/manager.go#L29-L44)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L20-L49)
|
|||
|
|
- [pkg/storage/minio.go](file://pkg/storage/minio.go#L57-L121)
|
|||
|
|
|
|||
|
|
## 结论
|
|||
|
|
- CarrotSkin 通过 RustFSConfig 将对象存储配置集中管理,并以环境变量驱动,实现灵活部署
|
|||
|
|
- 通过 RUSTFS_BUCKET_TEXTURES 与 RUSTFS_BUCKET_AVATARS 实现“材质/头像”两类资源的桶级隔离
|
|||
|
|
- 基于 minio-go 的预签名上传机制,既保证安全性又提升性能
|
|||
|
|
- 建议遵循安全最佳实践(最小权限、短期凭证、HTTPS)以保障生产安全
|
|||
|
|
|
|||
|
|
[本节为总结性内容,不涉及具体文件分析]
|
|||
|
|
|
|||
|
|
## 附录
|
|||
|
|
|
|||
|
|
### 环境变量与默认值对照
|
|||
|
|
- RUSTFS_ENDPOINT:RustFS 服务地址,默认值由 viper 设置
|
|||
|
|
- RUSTFS_ACCESS_KEY:访问密钥
|
|||
|
|
- RUSTFS_SECRET_KEY:私有密钥
|
|||
|
|
- RUSTFS_USE_SSL:是否启用 HTTPS
|
|||
|
|
- RUSTFS_BUCKET_TEXTURES:材质用途桶名
|
|||
|
|
- RUSTFS_BUCKET_AVATARS:头像用途桶名
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L190-L236)
|
|||
|
|
- [pkg/config/config.go](file://pkg/config/config.go#L238-L253)
|
|||
|
|
- [start.sh](file://start.sh#L22-L27)
|
|||
|
|
|
|||
|
|
### 启动脚本示例
|
|||
|
|
- start.sh 展示了如何设置对象存储相关环境变量,便于本地开发与测试
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [start.sh](file://start.sh#L22-L27)
|