chore(git): 更新.gitignore以忽略新的本地文件
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
This commit is contained in:
331
.qoder/repowiki/zh/content/配置管理/JWT配置.md
Normal file
331
.qoder/repowiki/zh/content/配置管理/JWT配置.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# JWT配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go)
|
||||
- [scripts/check-env.sh](file://scripts/check-env.sh)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件聚焦于CarrotSkin项目的JWT认证令牌配置,系统性说明以下内容:
|
||||
- jwt.secret与expire_hours两个核心配置项的作用与默认值
|
||||
- 如何通过环境变量JWT_SECRET与JWT_EXPIRE_HOURS进行安全覆盖
|
||||
- 基于JWTConfig结构体与认证服务代码的安全最佳实践
|
||||
- 密钥生成建议与有效期设置策略
|
||||
|
||||
## 项目结构
|
||||
围绕JWT配置的相关文件分布如下:
|
||||
- 配置加载与默认值:pkg/config/config.go、pkg/config/manager.go
|
||||
- JWT服务与管理器:pkg/auth/jwt.go、pkg/auth/manager.go
|
||||
- 认证处理器与服务层集成:internal/handler/auth_handler.go、internal/service/user_service.go
|
||||
- 环境变量检查脚本:scripts/check-env.sh
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
CFG["pkg/config/config.go<br/>加载与默认值"]
|
||||
CMGR["pkg/config/manager.go<br/>配置单例管理"]
|
||||
end
|
||||
subgraph "认证层"
|
||||
JCFG["pkg/auth/jwt.go<br/>JWT服务与声明"]
|
||||
JMGR["pkg/auth/manager.go<br/>JWT服务单例管理"]
|
||||
end
|
||||
subgraph "业务层"
|
||||
AH["internal/handler/auth_handler.go<br/>登录/注册接口"]
|
||||
US["internal/service/user_service.go<br/>登录/注册业务"]
|
||||
end
|
||||
subgraph "工具"
|
||||
ENV["scripts/check-env.sh<br/>环境变量检查"]
|
||||
end
|
||||
CFG --> CMGR
|
||||
CMGR --> JMGR
|
||||
JCFG --> JMGR
|
||||
AH --> US
|
||||
AH --> JMGR
|
||||
US --> JCFG
|
||||
ENV --> CFG
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L10-L71)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L41)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
- [scripts/check-env.sh](file://scripts/check-env.sh#L1-L78)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L10-L71)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L41)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
- [scripts/check-env.sh](file://scripts/check-env.sh#L1-L78)
|
||||
|
||||
## 核心组件
|
||||
- JWTConfig结构体
|
||||
- 字段:Secret(密钥)、ExpireHours(过期小时数)
|
||||
- 默认值:ExpireHours默认168小时(7天)
|
||||
- 环境变量映射:JWT_SECRET、JWT_EXPIRE_HOURS
|
||||
- JWTService
|
||||
- 作用:生成与验证JWT令牌;声明包含用户ID、用户名、角色及标准声明(签发时间、过期时间等)
|
||||
- 过期时间由expireHours决定,默认168小时
|
||||
- JWT服务管理器
|
||||
- 提供Init(cfg)一次性初始化,GetJWTService()/MustGetJWTService()获取全局实例
|
||||
- 认证服务集成
|
||||
- 登录/注册成功后,通过JWTService生成令牌并返回给客户端
|
||||
- 环境变量检查
|
||||
- 脚本会校验JWT_SECRET长度与默认值提示
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L67-L71)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L163-L165)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L220-L223)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L10-L71)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L41)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
- [scripts/check-env.sh](file://scripts/check-env.sh#L58-L77)
|
||||
|
||||
## 架构总览
|
||||
下图展示JWT配置从环境变量到服务使用的端到端流程。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant ENV as "环境变量"
|
||||
participant CFG as "配置加载(config.Load)"
|
||||
participant CMGR as "配置管理器(config.Init)"
|
||||
participant JMGR as "JWT管理器(auth.Init)"
|
||||
participant Jsvc as "JWT服务(auth.JWTService)"
|
||||
participant H as "认证处理器(handler.Login/Register)"
|
||||
participant S as "业务服务(service.LoginUser/RegisterUser)"
|
||||
ENV-->>CFG : "JWT_SECRET/JWT_EXPIRE_HOURS"
|
||||
CFG-->>CMGR : "加载并解析配置(Config)"
|
||||
CMGR-->>JMGR : "传入JWTConfig(Secret, ExpireHours)"
|
||||
JMGR-->>Jsvc : "创建JWTService实例"
|
||||
H->>S : "调用登录/注册业务"
|
||||
S->>Jsvc : "生成JWT令牌"
|
||||
Jsvc-->>S : "返回token"
|
||||
S-->>H : "返回token与用户信息"
|
||||
H-->>Client : "HTTP响应(含token)"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L23)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L32-L53)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### JWTConfig与默认值
|
||||
- 结构体定义
|
||||
- Secret:字符串,用于签名与验证JWT
|
||||
- ExpireHours:整数,令牌有效期(小时),默认168(7天)
|
||||
- 默认值来源
|
||||
- 通过Viper设置默认值,确保未提供环境变量时仍能运行
|
||||
- 环境变量映射
|
||||
- JWT_SECRET → jwt.secret
|
||||
- JWT_EXPIRE_HOURS → jwt.expire_hours
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L67-L71)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L163-L165)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L220-L223)
|
||||
|
||||
### JWTService与Claims
|
||||
- JWTService
|
||||
- 字段:secretKey、expireHours
|
||||
- 方法:GenerateToken、ValidateToken
|
||||
- Claims
|
||||
- 包含用户ID、用户名、角色以及标准声明(签发时间、过期时间、生效时间、发行者等)
|
||||
- 令牌生成
|
||||
- 使用HS256算法签名,过期时间基于expireHours计算
|
||||
- 令牌验证
|
||||
- 使用同一secretKey进行验证,若签名不符或过期则报错
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class JWTService {
|
||||
-string secretKey
|
||||
-int expireHours
|
||||
+GenerateToken(userID, username, role) string,error
|
||||
+ValidateToken(tokenString) Claims,error
|
||||
}
|
||||
class Claims {
|
||||
+int64 UserID
|
||||
+string Username
|
||||
+string Role
|
||||
+RegisteredClaims
|
||||
}
|
||||
JWTService --> Claims : "生成/验证"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L10-L71)
|
||||
|
||||
章节来源
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L10-L71)
|
||||
|
||||
### JWT服务管理器
|
||||
- Init(cfg)
|
||||
- 仅初始化一次,使用sync.Once保证幂等
|
||||
- 将cfg中的Secret与ExpireHours注入JWTService
|
||||
- GetJWTService/MustGetJWTService
|
||||
- 提供全局唯一实例访问;未初始化时报错或panic
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["调用 auth.Init(cfg)"]) --> Once{"是否已初始化?"}
|
||||
Once --> |否| Create["创建JWTService实例<br/>注入Secret/ExpireHours"]
|
||||
Once --> |是| Skip["跳过初始化"]
|
||||
Create --> Done(["完成"])
|
||||
Skip --> Done
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L23)
|
||||
|
||||
章节来源
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L41)
|
||||
|
||||
### 认证服务与JWT集成
|
||||
- 登录/注册成功后,业务层调用JWTService生成令牌
|
||||
- 处理器层接收令牌并返回给客户端
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as "客户端"
|
||||
participant H as "Handler(Login/Register)"
|
||||
participant S as "Service(LoginUser/RegisterUser)"
|
||||
participant J as "JWTService"
|
||||
C->>H : "POST /api/v1/auth/login"
|
||||
H->>S : "LoginUser(jwtService, ...)"
|
||||
S->>J : "GenerateToken(userID, username, role)"
|
||||
J-->>S : "token"
|
||||
S-->>H : "user + token"
|
||||
H-->>C : "200 OK + token"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L32-L53)
|
||||
|
||||
章节来源
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L32-L53)
|
||||
|
||||
### 环境变量覆盖与安全检查
|
||||
- 环境变量映射
|
||||
- JWT_SECRET → jwt.secret
|
||||
- JWT_EXPIRE_HOURS → jwt.expire_hours
|
||||
- 默认值
|
||||
- ExpireHours默认168(7天)
|
||||
- 安全检查
|
||||
- 脚本会检查JWT_SECRET长度是否小于32字符,并提示使用默认密钥的风险
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L220-L223)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L163-L165)
|
||||
- [scripts/check-env.sh](file://scripts/check-env.sh#L58-L77)
|
||||
|
||||
## 依赖关系分析
|
||||
- 配置层
|
||||
- config.Load负责从.env与环境变量加载配置,设置默认值并映射JWT相关键
|
||||
- config.Init提供全局配置单例
|
||||
- 认证层
|
||||
- auth.Init接收JWTConfig,创建JWTService实例
|
||||
- auth.GetJWTService/MustGetJWTService提供全局访问
|
||||
- 业务层
|
||||
- handler.Login/Register通过MustGetJWTService获取JWTService
|
||||
- service.LoginUser/RegisterUser调用JWTService生成令牌
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
CFG["config.Load"] --> CMGR["config.Init/GetConfig"]
|
||||
CMGR --> JMGR["auth.Init"]
|
||||
JMGR --> Jsvc["auth.JWTService"]
|
||||
AH["handler.Login/Register"] --> Jsvc
|
||||
US["service.LoginUser/RegisterUser"] --> Jsvc
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L23)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L18-L23)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L97-L147)
|
||||
- [internal/service/user_service.go](file://internal/service/user_service.go#L55-L107)
|
||||
|
||||
## 性能考量
|
||||
- 令牌生成与验证均为内存操作,开销极低
|
||||
- 过期时间越长,客户端缓存令牌的时间越久,减少鉴权次数;但会增加泄露风险
|
||||
- 建议在移动端或易泄露设备上缩短expire_hours,在可信环境适当延长
|
||||
|
||||
## 故障排查指南
|
||||
- JWT服务未初始化
|
||||
- 现象:调用GetJWTService/MustGetJWTService时报错或panic
|
||||
- 排查:确认已在应用启动阶段调用auth.Init(cfg)
|
||||
- 令牌无效
|
||||
- 现象:ValidateToken返回错误
|
||||
- 排查:确认使用相同的JWT_SECRET;检查网络传输是否篡改;核对过期时间
|
||||
- 环境变量未生效
|
||||
- 现象:JWT_EXPIRE_HOURS未按预期
|
||||
- 排查:确认环境变量名正确且已导出;检查.env文件路径与加载顺序
|
||||
|
||||
章节来源
|
||||
- [pkg/auth/manager.go](file://pkg/auth/manager.go#L26-L41)
|
||||
- [pkg/auth/jwt.go](file://pkg/auth/jwt.go#L55-L71)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
|
||||
## 结论
|
||||
- jwt.secret用于签名与验证JWT,必须保密且足够随机
|
||||
- expire_hours控制令牌有效期,默认168小时(7天),可通过JWT_EXPIRE_HOURS覆盖
|
||||
- 通过JWT_SECRET与JWT_EXPIRE_HOURS实现安全可控的令牌策略
|
||||
- 建议在生产环境使用长随机密钥,并根据业务场景调整有效期
|
||||
|
||||
## 附录
|
||||
|
||||
### 安全最佳实践
|
||||
- 密钥生成建议
|
||||
- 使用足够长度的随机字符串作为JWT_SECRET(建议≥32字符)
|
||||
- 避免使用默认密钥或弱口令
|
||||
- 有效期设置策略
|
||||
- 移动端/公共设备:较短有效期(如24-72小时)
|
||||
- 可信服务间:可适当延长(如7天)
|
||||
- 环境变量管理
|
||||
- 在部署时通过环境变量覆盖,避免硬编码
|
||||
- 使用脚本检查密钥长度与默认值风险
|
||||
|
||||
章节来源
|
||||
- [scripts/check-env.sh](file://scripts/check-env.sh#L58-L77)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L163-L165)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L220-L223)
|
||||
331
.qoder/repowiki/zh/content/配置管理/Redis配置.md
Normal file
331
.qoder/repowiki/zh/content/配置管理/Redis配置.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# Redis配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向CarrotSkin项目的开发者,系统性梳理Redis缓存系统的配置与使用方式,重点说明以下内容:
|
||||
- RedisConfig结构体中的各配置项(host、port、password、database、pool_size)的作用与默认值
|
||||
- pool_size参数对并发性能的影响机制
|
||||
- 如何通过REDIS_*环境变量动态覆盖配置
|
||||
- 结合RedisConfig结构体与连接初始化逻辑,给出多环境部署建议与连接池大小调优方法
|
||||
|
||||
## 项目结构
|
||||
Redis配置与使用涉及如下关键模块:
|
||||
- 配置加载与默认值:pkg/config
|
||||
- Redis客户端封装与连接初始化:pkg/redis
|
||||
- 应用启动流程:cmd/server/main.go
|
||||
- 业务使用示例:internal/handler与internal/service
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
CFG["pkg/config/config.go<br/>RedisConfig结构体与默认值"]
|
||||
CM["pkg/config/manager.go<br/>配置单例管理"]
|
||||
end
|
||||
subgraph "Redis层"
|
||||
RC["pkg/redis/redis.go<br/>Client封装与New初始化"]
|
||||
RM["pkg/redis/manager.go<br/>Init/GetClient/MustGetClient"]
|
||||
end
|
||||
subgraph "应用层"
|
||||
MAIN["cmd/server/main.go<br/>启动时初始化Redis"]
|
||||
AUTH["internal/handler/auth_handler.go<br/>使用MustGetClient()"]
|
||||
SVC["internal/service/verification_service.go<br/>验证码场景使用Redis"]
|
||||
end
|
||||
CFG --> CM
|
||||
CM --> MAIN
|
||||
MAIN --> RM
|
||||
RM --> RC
|
||||
AUTH --> RM
|
||||
SVC --> RC
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L49-L56)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L52-L61)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L27-L33)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L49-L56)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L52-L61)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L27-L33)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
|
||||
## 核心组件
|
||||
- RedisConfig结构体
|
||||
- 字段:host、port、password、database、pool_size
|
||||
- 默认值:由配置加载器在未显式提供时设置
|
||||
- 配置加载与环境变量覆盖
|
||||
- 默认值设置、环境变量前缀、映射与覆盖逻辑
|
||||
- Redis客户端封装与初始化
|
||||
- Client封装、New初始化、Ping连通性校验、连接池大小
|
||||
- 单例初始化与获取接口(Init/GetClient/MustGetClient)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L49-L56)
|
||||
- [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-L304)
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
|
||||
## 架构总览
|
||||
下图展示Redis配置与初始化在应用生命周期中的位置与交互。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as "main.go"
|
||||
participant CfgMgr as "config.Manager"
|
||||
participant Cfg as "config.Config"
|
||||
participant RedisMgr as "redis.Manager"
|
||||
participant RedisClient as "redis.Client"
|
||||
Main->>CfgMgr : Init()
|
||||
CfgMgr-->>Main : 配置实例
|
||||
Main->>RedisMgr : Init(RedisConfig, Logger)
|
||||
RedisMgr->>RedisClient : New(cfg, logger)
|
||||
RedisClient->>RedisClient : Ping()连通性校验
|
||||
RedisMgr-->>Main : 初始化完成
|
||||
Main-->>Main : 启动HTTP服务
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L61)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### RedisConfig结构体与默认值
|
||||
- 字段定义与含义
|
||||
- host:Redis服务器地址,默认值由配置加载器设置
|
||||
- port:Redis服务器端口,默认值由配置加载器设置
|
||||
- password:Redis认证密码,默认值由配置加载器设置
|
||||
- database:Redis数据库索引,默认值由配置加载器设置
|
||||
- pool_size:Redis连接池大小,默认值由配置加载器设置
|
||||
- 默认值来源
|
||||
- 配置加载器在未显式提供时设置默认值,确保应用在最小配置下仍可运行
|
||||
- 环境变量映射
|
||||
- REDIS_HOST、REDIS_PORT、REDIS_PASSWORD、REDIS_DATABASE
|
||||
- REDIS_POOL_SIZE用于覆盖连接池大小
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L49-L56)
|
||||
- [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-L304)
|
||||
|
||||
### 连接初始化与Ping校验
|
||||
- 初始化流程
|
||||
- 通过redis.NewClient创建客户端,使用RedisConfig中的host/port/password/database/pool_size
|
||||
- 使用Ping进行连通性校验,失败则返回错误
|
||||
- 初始化成功后记录日志,包含host/port/database
|
||||
- 并发与线程安全
|
||||
- Redis初始化采用once.Do保证全局仅初始化一次
|
||||
- GetClient/MustGetClient提供线程安全的获取方式
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入Init(cfg, logger)"]) --> Once["once.Do执行"]
|
||||
Once --> NewClient["创建redis.Client(options)"]
|
||||
NewClient --> Ping["Ping()连通性校验"]
|
||||
Ping --> Ok{"Ping成功?"}
|
||||
Ok --> |否| Err["返回错误"]
|
||||
Ok --> |是| Log["记录连接成功日志"]
|
||||
Log --> Done(["返回Client实例"])
|
||||
Err --> Done
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
|
||||
章节来源
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
|
||||
### 环境变量动态覆盖机制
|
||||
- 环境变量前缀与映射
|
||||
- 配置加载器设置环境变量前缀为CARROTSKIN,并将redis.*字段绑定到REDIS_*环境变量
|
||||
- 动态覆盖逻辑
|
||||
- 在解析默认值与环境变量后,额外处理REDIS_POOL_SIZE以覆盖连接池大小
|
||||
- 使用建议
|
||||
- 开发环境可使用较小pool_size;生产环境根据QPS与并发峰值评估后设置
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L236)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L304)
|
||||
|
||||
### 业务使用示例
|
||||
- 验证码场景
|
||||
- 发送验证码前检查频率限制键是否存在
|
||||
- 将验证码写入Redis并设置过期时间
|
||||
- 发送邮件失败时删除验证码键
|
||||
- 登录/注册/重置密码
|
||||
- Handler层通过MustGetClient()获取Redis客户端
|
||||
- Service层调用Redis进行验证码校验与清理
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant H as "auth_handler"
|
||||
participant S as "verification_service"
|
||||
participant R as "redis.Client"
|
||||
H->>R : MustGetClient()
|
||||
H->>S : SendVerificationCode(ctx, R, emailService, email, type)
|
||||
S->>R : Exists(rateLimitKey)
|
||||
alt 存在频率限制
|
||||
S-->>H : 返回“发送过于频繁”
|
||||
else 无频率限制
|
||||
S->>R : Set(codeKey, code, expiration)
|
||||
S->>R : Set(rateLimitKey, "1", rateLimit)
|
||||
S-->>H : 发送成功
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L27-L33)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L31-L46)
|
||||
|
||||
章节来源
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L27-L33)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
|
||||
## 依赖关系分析
|
||||
- 配置到Redis的依赖链
|
||||
- config.Manager -> config.Config -> redis.Manager -> redis.Client
|
||||
- 启动阶段依赖
|
||||
- main.go在启动时顺序初始化配置、日志、数据库、JWT、Redis、对象存储、邮件服务
|
||||
- 业务依赖
|
||||
- Handler与Service通过redis.Manager提供的单例接口使用Redis
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
CFG["config.Config"] --> RM["redis.Manager"]
|
||||
RM --> RC["redis.Client"]
|
||||
MAIN["cmd/server/main.go"] --> RM
|
||||
AUTH["internal/handler/auth_handler.go"] --> RM
|
||||
SVC["internal/service/verification_service.go"] --> RC
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L61)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L27-L33)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L61)
|
||||
- [pkg/config/manager.go](file://pkg/config/manager.go#L19-L46)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L20-L46)
|
||||
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L27-L33)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
|
||||
## 性能考量
|
||||
- pool_size对并发性能的影响机制
|
||||
- 连接池大小决定同时可用的底层TCP连接数
|
||||
- 在高并发场景下,若pool_size过小,可能出现连接争用与等待,导致延迟上升
|
||||
- 若pool_size过大,会增加Redis端的连接管理开销与资源占用
|
||||
- 调优建议
|
||||
- 基准测试:在预生产环境模拟峰值QPS,逐步提升pool_size并观察延迟与错误率
|
||||
- 观察指标:监控Redis连接数、等待队列长度、命令执行延迟
|
||||
- 平衡策略:在满足延迟目标的前提下,尽量保持pool_size适中,避免过度放大
|
||||
- 与业务场景的匹配
|
||||
- 验证码发送/校验属于短时高频写入场景,适度增大pool_size有助于降低写入抖动
|
||||
- 读多写少的场景可结合Pipeline/TxPipeline减少RTT,进一步提升吞吐
|
||||
|
||||
[本节为通用性能讨论,不直接分析具体文件]
|
||||
|
||||
## 故障排查指南
|
||||
- 初始化失败
|
||||
- 症状:启动时报Redis连接失败
|
||||
- 排查要点:确认REDIS_HOST/REDIS_PORT/REDIS_PASSWORD/REDIS_DATABASE是否正确;检查网络连通性;确认Redis服务状态
|
||||
- 参考实现:初始化时进行Ping校验,失败返回错误
|
||||
- 未初始化即使用
|
||||
- 症状:调用MustGetClient()时panic或GetClient()返回错误
|
||||
- 排查要点:确保在main中先调用redis.Init(),再启动HTTP服务
|
||||
- 频繁超时或错误
|
||||
- 症状:业务调用Redis出现超时或错误
|
||||
- 排查要点:检查pool_size是否过小;确认Redis资源瓶颈;优化业务逻辑减少阻塞操作
|
||||
- 验证码发送过于频繁
|
||||
- 症状:提示发送过于频繁
|
||||
- 排查要点:检查频率限制键是否存在且未过期;确认业务逻辑正确清理
|
||||
|
||||
章节来源
|
||||
- [pkg/redis/redis.go](file://pkg/redis/redis.go#L21-L52)
|
||||
- [pkg/redis/manager.go](file://pkg/redis/manager.go#L31-L46)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L52-L61)
|
||||
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L77)
|
||||
|
||||
## 结论
|
||||
- RedisConfig提供了简洁明确的配置项,配合默认值与环境变量覆盖,可在多环境中快速部署
|
||||
- pool_size直接影响并发性能,应结合业务负载与Redis资源进行调优
|
||||
- 通过once.Do保证Redis客户端单例初始化,配合MustGetClient/GetClient简化了业务侧使用
|
||||
- 建议在生产环境启用合理的pool_size,并持续监控连接池利用率与延迟指标
|
||||
|
||||
[本节为总结性内容,不直接分析具体文件]
|
||||
|
||||
## 附录
|
||||
|
||||
### 配置项与默认值对照表
|
||||
- host:Redis主机地址,默认值由配置加载器设置
|
||||
- port:Redis端口,默认值由配置加载器设置
|
||||
- password:Redis认证密码,默认值由配置加载器设置
|
||||
- database:Redis数据库索引,默认值由配置加载器设置
|
||||
- pool_size:Redis连接池大小,默认值由配置加载器设置
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L49-L56)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
|
||||
### 环境变量覆盖清单
|
||||
- REDIS_HOST:覆盖host
|
||||
- REDIS_PORT:覆盖port
|
||||
- REDIS_PASSWORD:覆盖password
|
||||
- REDIS_DATABASE:覆盖database
|
||||
- REDIS_POOL_SIZE:覆盖pool_size
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L236)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L304)
|
||||
|
||||
### 多环境部署建议
|
||||
- 开发环境
|
||||
- 使用较小pool_size(如默认值),便于本地调试
|
||||
- 通过REDIS_*环境变量快速切换Redis实例
|
||||
- 预生产/生产环境
|
||||
- 基于基准测试确定pool_size,结合监控指标持续优化
|
||||
- 使用独立database索引隔离不同环境数据
|
||||
- 对password进行严格管理,避免明文配置
|
||||
|
||||
[本节为通用建议,不直接分析具体文件]
|
||||
305
.qoder/repowiki/zh/content/配置管理/对象存储配置.md
Normal file
305
.qoder/repowiki/zh/content/配置管理/对象存储配置.md
Normal file
@@ -0,0 +1,305 @@
|
||||
# 对象存储配置
|
||||
|
||||
<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)
|
||||
364
.qoder/repowiki/zh/content/配置管理/数据库配置.md
Normal file
364
.qoder/repowiki/zh/content/配置管理/数据库配置.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# 数据库配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [pkg/config/config.go](file://pkg/config/config.go)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.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 项目的数据库连接与连接池配置,系统性说明以下内容:
|
||||
- 连接参数 database.driver、host、port、username、password、database、ssl_mode、timezone 的用途与默认值来源
|
||||
- 连接池参数 max_idle_conns、max_open_conns、conn_max_lifetime 的工作机制与性能影响
|
||||
- 如何通过 DATABASE_* 环境变量覆盖默认配置
|
||||
- 结合 DatabaseConfig 结构体与数据库初始化流程的最佳实践,包含生产环境安全建议与连接池调优策略
|
||||
|
||||
## 项目结构
|
||||
数据库相关能力由配置层与数据库层协同实现:
|
||||
- 配置层负责加载默认值、绑定环境变量映射,并支持从环境变量覆盖连接池参数
|
||||
- 数据库层负责根据配置构建 DSN、初始化 GORM 连接、设置连接池并进行连通性测试
|
||||
- 应用入口在启动时加载配置、初始化数据库并执行迁移
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
CFG["pkg/config/config.go<br/>DatabaseConfig/默认值/环境映射"]
|
||||
end
|
||||
subgraph "数据库层"
|
||||
DBM["pkg/database/manager.go<br/>Init/GetDB/AutoMigrate/Close"]
|
||||
PG["pkg/database/postgres.go<br/>New/GetDSN"]
|
||||
end
|
||||
subgraph "应用入口"
|
||||
MAIN["cmd/server/main.go<br/>加载配置/初始化数据库/迁移"]
|
||||
end
|
||||
ENV["环境变量<br/>DATABASE_*"]
|
||||
ENV --> CFG
|
||||
CFG --> DBM
|
||||
DBM --> PG
|
||||
MAIN --> CFG
|
||||
MAIN --> DBM
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L22-L50)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L50)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L22-L50)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L50)
|
||||
|
||||
## 核心组件
|
||||
- DatabaseConfig 结构体:承载数据库连接与连接池配置
|
||||
- 配置加载与覆盖:默认值、环境变量映射、连接池参数覆盖
|
||||
- 数据库初始化:构建 DSN、初始化 GORM、设置连接池、Ping 测试
|
||||
- 应用启动流程:加载配置 → 初始化数据库 → 自动迁移
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L34-L47)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L210)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L280)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L22-L50)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L50)
|
||||
|
||||
## 架构总览
|
||||
下图展示从配置到数据库连接的关键调用链路与职责分工。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Entrypoint as "应用入口(main.go)"
|
||||
participant Cfg as "配置(Config.Load)"
|
||||
participant DBMgr as "数据库管理器(database.Init)"
|
||||
participant DB as "数据库(New)"
|
||||
participant SQL as "底层sql.DB"
|
||||
Entrypoint->>Cfg : "加载配置"
|
||||
Cfg-->>Entrypoint : "返回完整配置"
|
||||
Entrypoint->>DBMgr : "Init(DatabaseConfig)"
|
||||
DBMgr->>DB : "New(DatabaseConfig)"
|
||||
DB->>DB : "构造DSN"
|
||||
DB->>SQL : "gorm.Open + 获取*sql.DB"
|
||||
DB->>SQL : "SetMaxIdleConns/SetMaxOpenConns/SetConnMaxLifetime"
|
||||
DB->>SQL : "Ping() 测试连接"
|
||||
DB-->>DBMgr : "*gorm.DB"
|
||||
DBMgr-->>Entrypoint : "初始化完成"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L50)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L22-L33)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### DatabaseConfig 字段与用途
|
||||
- database.driver
|
||||
- 作用:驱动类型标识,用于控制日志级别与后续扩展点
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_DRIVER
|
||||
- database.host
|
||||
- 作用:数据库主机地址
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_HOST
|
||||
- database.port
|
||||
- 作用:数据库端口
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_PORT
|
||||
- database.username
|
||||
- 作用:数据库用户名
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_USERNAME
|
||||
- database.password
|
||||
- 作用:数据库密码
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_PASSWORD
|
||||
- database.database
|
||||
- 作用:数据库名
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_NAME
|
||||
- database.ssl_mode
|
||||
- 作用:SSL 模式(如 disable/require 等),影响 TLS 连接
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_SSL_MODE
|
||||
- database.timezone
|
||||
- 作用:时区设置,影响时间字段的时区行为
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量映射:DATABASE_TIMEZONE
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L34-L47)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L210)
|
||||
|
||||
### 连接池配置项与工作机制
|
||||
- max_idle_conns
|
||||
- 作用:最大空闲连接数,控制连接池中空闲连接上限
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量覆盖:DATABASE_MAX_IDLE_CONNS
|
||||
- max_open_conns
|
||||
- 作用:最大打开连接数,限制并发连接上限
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量覆盖:DATABASE_MAX_OPEN_CONNS
|
||||
- conn_max_lifetime
|
||||
- 作用:连接最大存活时间,到期后连接会被回收
|
||||
- 默认值:来自默认配置
|
||||
- 环境变量覆盖:DATABASE_CONN_MAX_LIFETIME(支持时长字符串,如“1h”)
|
||||
|
||||
这些参数在 New 中通过底层 sql.DB 设置,并在 Ping 成功后生效。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L34-L47)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L280)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L49-L53)
|
||||
|
||||
### 环境变量覆盖与默认值
|
||||
- 默认值来源
|
||||
- 通过 viper.SetDefault 设置,确保即使未提供对应环境变量也能有合理默认
|
||||
- 环境变量映射
|
||||
- 使用 viper.BindEnv 将配置键映射到 DATABASE_* 前缀的环境变量
|
||||
- 连接池参数覆盖
|
||||
- 通过 overrideFromEnv 从环境变量读取整型或时长字符串并覆盖默认值
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L210)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L280)
|
||||
|
||||
### 数据库初始化流程与 DSN 构造
|
||||
- DSN 构造
|
||||
- New 中依据 DatabaseConfig 组装 DSN,包含 host、port、user、password、dbname、sslmode、TimeZone
|
||||
- GORM 初始化
|
||||
- 根据 driver 决定日志级别;禁用迁移时的外键约束以避免循环依赖
|
||||
- 连接池设置
|
||||
- SetMaxIdleConns、SetMaxOpenConns、SetConnMaxLifetime
|
||||
- 连通性测试
|
||||
- Ping 成功后返回 gorm.DB 实例
|
||||
|
||||
章节来源
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
|
||||
### 应用启动中的数据库初始化
|
||||
- 配置加载:Load 会加载 .env 并解析为 Config
|
||||
- 数据库初始化:Init 接收 DatabaseConfig,内部调用 New 完成连接与池设置
|
||||
- 自动迁移:AutoMigrate 按顺序迁移模型,确保外键依赖关系正确
|
||||
- 资源清理:Close 关闭底层 sql.DB
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L50)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L22-L50)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L52-L99)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L101-L114)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Config {
|
||||
+ServerConfig Server
|
||||
+DatabaseConfig Database
|
||||
+RedisConfig Redis
|
||||
+RustFSConfig RustFS
|
||||
+JWTConfig JWT
|
||||
+CasbinConfig Casbin
|
||||
+LogConfig Log
|
||||
+UploadConfig Upload
|
||||
+EmailConfig Email
|
||||
}
|
||||
class DatabaseConfig {
|
||||
+string Driver
|
||||
+string Host
|
||||
+int Port
|
||||
+string Username
|
||||
+string Password
|
||||
+string Database
|
||||
+string SSLMode
|
||||
+string Timezone
|
||||
+int MaxIdleConns
|
||||
+int MaxOpenConns
|
||||
+duration ConnMaxLifetime
|
||||
}
|
||||
class Manager {
|
||||
+Init(cfg, logger) error
|
||||
+GetDB() (*gorm.DB, error)
|
||||
+MustGetDB() *gorm.DB
|
||||
+AutoMigrate(logger) error
|
||||
+Close() error
|
||||
}
|
||||
class Postgres {
|
||||
+New(cfg) (*gorm.DB, error)
|
||||
+GetDSN(cfg) string
|
||||
}
|
||||
Config --> DatabaseConfig : "包含"
|
||||
Manager --> DatabaseConfig : "使用"
|
||||
Postgres --> DatabaseConfig : "使用"
|
||||
Manager --> Postgres : "调用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L13-L24)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L34-L47)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L22-L50)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
|
||||
## 性能考量
|
||||
- 连接池参数建议
|
||||
- max_idle_conns:建议与 max_open_conns 保持一定比例,避免过多空闲连接占用资源
|
||||
- max_open_conns:应结合数据库最大连接数与应用并发量综合评估,避免超过数据库限制导致连接排队
|
||||
- conn_max_lifetime:建议设置为小于数据库连接超时阈值,确保连接健康与复用效率
|
||||
- 日志级别
|
||||
- 当 driver 为 postgres 时,GORM 日志级别提升为 Info,便于调试;在生产环境可考虑降低日志级别以减少开销
|
||||
- 迁移策略
|
||||
- AutoMigrate 顺序需保证被引用表先于引用表创建,避免外键约束冲突
|
||||
|
||||
章节来源
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L25-L32)
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L52-L99)
|
||||
|
||||
## 故障排查指南
|
||||
- 未初始化即使用数据库
|
||||
- 现象:调用 GetDB 返回错误提示“数据库未初始化”
|
||||
- 处理:确保在应用启动阶段先调用 database.Init
|
||||
- 连接失败
|
||||
- 检查 DSN 参数是否正确(host/port/username/password/database/ssl_mode/timezone)
|
||||
- 确认数据库可达与凭据有效
|
||||
- 连接池异常
|
||||
- 检查 max_idle_conns、max_open_conns 是否设置过小或过大
|
||||
- 检查 conn_max_lifetime 是否导致频繁重建连接
|
||||
- 环境变量未生效
|
||||
- 确认环境变量前缀与键名匹配(DATABASE_*)
|
||||
- 确认 overrideFromEnv 可正确解析整型与 duration 类型
|
||||
|
||||
章节来源
|
||||
- [pkg/database/manager.go](file://pkg/database/manager.go#L35-L41)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L13-L60)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L210)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L280)
|
||||
|
||||
## 结论
|
||||
- CarrotSkin 的数据库配置采用“默认值 + 环境变量覆盖”的设计,既保证开箱即用,又允许灵活定制
|
||||
- 连接池参数通过 DATABASE_MAX_IDLE_CONNS、DATABASE_MAX_OPEN_CONNS、DATABASE_CONN_MAX_LIFETIME 进行覆盖,建议结合业务并发与数据库能力进行调优
|
||||
- 生产环境建议启用 SSL(ssl_mode)、严格凭据管理与最小权限原则,并适当降低日志级别以优化性能
|
||||
|
||||
## 附录
|
||||
|
||||
### 环境变量与默认值对照表
|
||||
- database.driver
|
||||
- 环境变量:DATABASE_DRIVER
|
||||
- 默认值:postgres
|
||||
- database.host
|
||||
- 环境变量:DATABASE_HOST
|
||||
- 默认值:localhost
|
||||
- database.port
|
||||
- 环境变量:DATABASE_PORT
|
||||
- 默认值:5432
|
||||
- database.username
|
||||
- 环境变量:DATABASE_USERNAME
|
||||
- 默认值:空字符串
|
||||
- database.password
|
||||
- 环境变量:DATABASE_PASSWORD
|
||||
- 默认值:空字符串
|
||||
- database.database
|
||||
- 环境变量:DATABASE_NAME
|
||||
- 默认值:空字符串
|
||||
- database.ssl_mode
|
||||
- 环境变量:DATABASE_SSL_MODE
|
||||
- 默认值:disable
|
||||
- database.timezone
|
||||
- 环境变量:DATABASE_TIMEZONE
|
||||
- 默认值:Asia/Shanghai
|
||||
- database.max_idle_conns
|
||||
- 环境变量:DATABASE_MAX_IDLE_CONNS
|
||||
- 默认值:10
|
||||
- database.max_open_conns
|
||||
- 环境变量:DATABASE_MAX_OPEN_CONNS
|
||||
- 默认值:100
|
||||
- database.conn_max_lifetime
|
||||
- 环境变量:DATABASE_CONN_MAX_LIFETIME
|
||||
- 默认值:1h
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L190-L210)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L280)
|
||||
|
||||
### 生产环境安全与连接池调优建议
|
||||
- 安全建议
|
||||
- 将 ssl_mode 设为 require 或 verify-full(视数据库支持而定),并配合证书校验
|
||||
- 使用专用数据库用户与最小权限策略,定期轮换密码
|
||||
- 通过环境变量注入敏感信息,避免硬编码
|
||||
- 连接池调优
|
||||
- 初步以 max_idle_conns ≈ 1/10 max_open_conns 开始,结合压测结果调整
|
||||
- 将 conn_max_lifetime 设置为略小于数据库连接超时阈值,平衡资源回收与连接复用
|
||||
- 监控数据库连接数与等待队列,动态调整 max_open_conns
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L135-L188)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L238-L280)
|
||||
- [pkg/database/postgres.go](file://pkg/database/postgres.go#L49-L53)
|
||||
|
||||
### 启动脚本中的数据库环境变量示例
|
||||
- 示例脚本展示了如何设置 DATABASE_HOST、DATABASE_PORT、DATABASE_USERNAME、DATABASE_PASSWORD、DATABASE_NAME、DATABASE_SSL_MODE、DATABASE_TIMEZONE 等环境变量
|
||||
|
||||
章节来源
|
||||
- [start.sh](file://start.sh#L1-L41)
|
||||
367
.qoder/repowiki/zh/content/配置管理/日志配置.md
Normal file
367
.qoder/repowiki/zh/content/配置管理/日志配置.md
Normal file
@@ -0,0 +1,367 @@
|
||||
# 日志配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go)
|
||||
- [go.mod](file://go.mod)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向 CarrotSkin 项目的开发者与运维人员,系统性说明日志系统的配置与使用方式。重点围绕以下配置项展开:log.level、format、output、max_size、max_backups、max_age 和 compress;并结合 LogConfig 结构体与实际代码实现,给出不同日志级别选择策略、JSON 格式与文本格式的适用场景、以及基于大小与天数的日志轮转工作机制。最后提供生产环境监控集成建议与最佳实践。
|
||||
|
||||
## 项目结构
|
||||
日志系统由“配置加载层”“日志工厂层”“全局管理器层”“中间件与业务使用层”四部分组成:
|
||||
- 配置加载层:从环境变量加载并解析为 Config,其中包含 LogConfig 字段。
|
||||
- 日志工厂层:根据 LogConfig 构建 zap.Logger。
|
||||
- 全局管理器层:提供 Init、GetLogger、MustGetLogger 等接口,确保单例与线程安全。
|
||||
- 中间件与业务使用层:通过中间件注入日志实例,统一记录 HTTP 请求与异常恢复。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["配置加载<br/>pkg/config/config.go"] --> B["日志工厂<br/>pkg/logger/logger.go"]
|
||||
B --> C["全局管理器<br/>pkg/logger/manager.go"]
|
||||
C --> D["中间件使用<br/>internal/middleware/logger.go"]
|
||||
C --> E["恢复中间件<br/>internal/middleware/recovery.go"]
|
||||
C --> F["应用入口初始化<br/>cmd/server/main.go"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
## 核心组件
|
||||
- LogConfig 结构体:定义日志系统的核心配置项,来源于环境变量映射。
|
||||
- New:根据 LogConfig 构建 zap.Logger,支持 JSON/Console 编码器、stdout 或文件输出。
|
||||
- Init/GetLogger/MustGetLogger:全局单例管理,保证线程安全与幂等初始化。
|
||||
- 中间件 Logger/Recovery:在请求处理前后记录日志,并在 panic 时记录堆栈与上下文。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
|
||||
## 架构总览
|
||||
下图展示了从配置到日志输出的关键流程:应用启动时加载配置,初始化日志管理器,随后中间件与业务代码通过全局日志实例进行记录。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as "应用入口<br/>cmd/server/main.go"
|
||||
participant Cfg as "配置加载<br/>pkg/config/config.go"
|
||||
participant LMgr as "日志管理器<br/>pkg/logger/manager.go"
|
||||
participant LNew as "日志工厂<br/>pkg/logger/logger.go"
|
||||
participant MW as "中间件<br/>internal/middleware/logger.go"
|
||||
participant Rec as "恢复中间件<br/>internal/middleware/recovery.go"
|
||||
App->>Cfg : 加载配置
|
||||
Cfg-->>App : 返回 Config(LogConfig)
|
||||
App->>LMgr : Init(LogConfig)
|
||||
LMgr->>LNew : New(LogConfig)
|
||||
LNew-->>LMgr : 返回 zap.Logger
|
||||
LMgr-->>App : 初始化完成
|
||||
App->>MW : 注入日志实例
|
||||
App->>Rec : 注入日志实例
|
||||
MW-->>App : 记录请求日志
|
||||
Rec-->>App : 记录 panic 与堆栈
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L40)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L20-L29)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L14-L68)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L10-L39)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L11-L29)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 配置项详解与选择策略
|
||||
- log.level
|
||||
- 取值范围:debug、info、warn、error,默认 info。
|
||||
- 选择策略:
|
||||
- 开发/调试:debug,便于定位问题。
|
||||
- 生产:info,平衡可观测性与性能;仅在需要深入排查时临时提升到 debug。
|
||||
- 严重问题:error,聚焦错误事件,避免过多噪声。
|
||||
- log.format
|
||||
- 取值:console、json。
|
||||
- 适用场景:
|
||||
- console:本地开发终端阅读友好,便于快速定位。
|
||||
- json:便于日志收集与结构化分析,适合生产与集中化监控。
|
||||
- log.output
|
||||
- 取值:空/“stdout”表示输出到标准输出;其他路径将自动创建目录并写入文件。
|
||||
- 适用场景:
|
||||
- 容器化部署:stdout,配合容器日志采集。
|
||||
- 传统部署:文件路径,结合日志轮转策略。
|
||||
- log.max_size、log.max_backups、log.max_age、log.compress
|
||||
- 作用:控制日志轮转策略(按大小与天数)与压缩开关。
|
||||
- 工作机制(基于大小与天数):
|
||||
- 当单个日志文件达到 max_size(MB)时触发轮转。
|
||||
- 最多保留 max_backups 个历史备份文件。
|
||||
- 历史文件保留不超过 max_age(天)。
|
||||
- compress=true 时对旧文件进行压缩,节省磁盘空间。
|
||||
- 注意:当前代码实现中并未直接使用上述字段进行轮转配置,而是采用文件输出与基础写入同步。若需启用基于大小/天数的轮转,可在日志工厂中引入外部轮转库(如 lumberjack)并传入上述参数。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L170-L178)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L43-L60)
|
||||
|
||||
### 日志级别选择策略
|
||||
- debug:用于开发阶段的详细追踪,包含大量上下文信息。
|
||||
- info:生产环境默认级别,记录关键业务事件与系统状态。
|
||||
- warn:潜在问题或异常流程,需关注但不影响整体运行。
|
||||
- error:错误事件,必须处理与上报。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L16-L28)
|
||||
|
||||
### JSON 格式与文本格式的适用场景
|
||||
- JSON:
|
||||
- 优点:结构化强,便于日志聚合、检索与告警。
|
||||
- 适用:生产环境、集中化日志平台(如 ELK、Loki、Cloud Logging)。
|
||||
- Console:
|
||||
- 优点:人类可读性强,适合本地开发与快速排障。
|
||||
- 适用:本地调试、临时诊断。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L30-L41)
|
||||
|
||||
### 日志轮转策略(基于大小与天数)
|
||||
- 当前实现要点:
|
||||
- 输出到文件时会自动创建目录并追加写入。
|
||||
- 未显式配置基于大小/天数的轮转。
|
||||
- 建议扩展方案:
|
||||
- 引入外部轮转库(如 lumberjack),在 New 中根据 max_size、max_backups、max_age、compress 进行轮转配置。
|
||||
- 将轮转配置作为可选参数传入,保持现有接口兼容。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L43-L60)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
|
||||
### 日志工厂与全局管理器
|
||||
- New:根据 LogConfig 构建 zap.Logger,设置级别、编码器与输出目标。
|
||||
- Init/GetLogger/MustGetLogger:提供线程安全的单例初始化与获取能力,避免重复初始化。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LogConfig {
|
||||
+string level
|
||||
+string format
|
||||
+string output
|
||||
+int max_size
|
||||
+int max_backups
|
||||
+int max_age
|
||||
+bool compress
|
||||
}
|
||||
class LoggerFactory {
|
||||
+New(cfg LogConfig) *zap.Logger
|
||||
}
|
||||
class LogManager {
|
||||
+Init(cfg LogConfig) error
|
||||
+GetLogger() (*zap.Logger, error)
|
||||
+MustGetLogger() *zap.Logger
|
||||
}
|
||||
LogConfig --> LoggerFactory : "输入"
|
||||
LoggerFactory --> LogManager : "被调用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L14-L68)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L20-L46)
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L14-L68)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
|
||||
### 中间件与业务使用
|
||||
- Logger 中间件:记录每次 HTTP 请求的方法、路径、状态码、耗时、客户端 IP、User-Agent 等。
|
||||
- Recovery 中间件:捕获 panic 并记录错误、路径、方法、IP 与完整堆栈,返回统一错误响应。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant Router as "Gin 路由"
|
||||
participant MW as "日志中间件"
|
||||
participant Handler as "业务处理器"
|
||||
participant Rec as "恢复中间件"
|
||||
Client->>Router : 发起请求
|
||||
Router->>MW : 进入日志中间件
|
||||
MW->>MW : 记录请求开始时间与上下文
|
||||
MW->>Handler : 继续处理
|
||||
Handler-->>MW : 返回响应
|
||||
MW->>MW : 记录状态码、耗时、IP、UA
|
||||
MW-->>Router : 返回响应
|
||||
Note over MW : 若发生 panic,由恢复中间件接管
|
||||
Router->>Rec : 进入恢复中间件
|
||||
Rec->>Rec : 记录错误与堆栈
|
||||
Rec-->>Client : 返回 500 错误
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L10-L39)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L11-L29)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L81-L90)
|
||||
|
||||
章节来源
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L81-L90)
|
||||
|
||||
## 依赖关系分析
|
||||
- 外部依赖:zap 用于高性能日志记录;viper 用于配置加载;godotenv 用于 .env 支持。
|
||||
- 内部依赖:配置模块提供 LogConfig;日志模块提供 Init/GetLogger;中间件依赖日志实例。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
Z["go.uber.org/zap"]
|
||||
V["github.com/spf13/viper"]
|
||||
D["github.com/joho/godotenv"]
|
||||
end
|
||||
subgraph "内部模块"
|
||||
CFG["pkg/config/config.go"]
|
||||
LOGF["pkg/logger/logger.go"]
|
||||
LOGM["pkg/logger/manager.go"]
|
||||
MWL["internal/middleware/logger.go"]
|
||||
MWR["internal/middleware/recovery.go"]
|
||||
MAIN["cmd/server/main.go"]
|
||||
end
|
||||
V --> CFG
|
||||
D --> CFG
|
||||
CFG --> LOGM
|
||||
LOGM --> LOGF
|
||||
MAIN --> LOGM
|
||||
MAIN --> MWL
|
||||
MAIN --> MWR
|
||||
Z --> LOGF
|
||||
Z --> MWL
|
||||
Z --> MWR
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [go.mod](file://go.mod#L7-L22)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
章节来源
|
||||
- [go.mod](file://go.mod#L7-L22)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
## 性能考量
|
||||
- 使用 zap:具备高性能与零分配特性,适合高并发场景。
|
||||
- 选择合适的日志级别:生产环境默认 info,避免 debug 的额外开销。
|
||||
- 输出目标选择:stdout 便于容器日志采集;文件输出需注意磁盘 IO 与轮转策略。
|
||||
- 压缩与保留策略:合理设置 max_size、max_backups、max_age 与 compress,平衡磁盘占用与检索效率。
|
||||
|
||||
## 故障排查指南
|
||||
- 未初始化日志即使用:
|
||||
- 现象:调用 GetLogger 返回错误提示“日志未初始化,请先调用 logger.Init()”。
|
||||
- 排查:确认应用入口是否在启动时调用了 logger.Init(cfg.Log)。
|
||||
- 输出到文件失败:
|
||||
- 现象:初始化日志时报错,无法打开文件。
|
||||
- 排查:检查 log.output 指定路径是否存在写权限,目录是否可创建。
|
||||
- panic 未记录:
|
||||
- 现象:服务崩溃但无日志记录。
|
||||
- 排查:确认已注册 Recovery 中间件并注入了日志实例。
|
||||
- 日志轮转未生效:
|
||||
- 现象:日志文件持续增大。
|
||||
- 排查:当前实现未使用 max_size/max_backups/max_age/compress 进行轮转,需扩展轮转逻辑。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L31-L37)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L43-L60)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L11-L29)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L81-L90)
|
||||
|
||||
## 结论
|
||||
- CarrotSkin 的日志系统以 zap 为核心,通过配置驱动实现灵活的日志级别、编码器与输出目标切换。
|
||||
- 当前未直接启用基于大小/天数的轮转,建议在日志工厂中引入轮转库并使用 LogConfig 的 max_size、max_backups、max_age、compress 字段。
|
||||
- 在生产环境中推荐使用 JSON 格式与 stdout 输出,结合集中化日志平台与告警策略,提升可观测性与可维护性。
|
||||
|
||||
## 附录
|
||||
|
||||
### 配置项一览与默认值
|
||||
- log.level:默认 info
|
||||
- log.format:默认 json
|
||||
- log.output:默认 logs/app.log(文件输出)
|
||||
- log.max_size:默认 100 MB
|
||||
- log.max_backups:默认 3
|
||||
- log.max_age:默认 28 天
|
||||
- log.compress:默认 true
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L170-L178)
|
||||
|
||||
### 环境变量映射
|
||||
- LOG_LEVEL → log.level
|
||||
- LOG_FORMAT → log.format
|
||||
- LOG_OUTPUT → log.output
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L224-L228)
|
||||
|
||||
### 配置示例与最佳实践
|
||||
- 示例一:本地开发(控制台输出,便于阅读)
|
||||
- LOG_LEVEL=debug
|
||||
- LOG_FORMAT=console
|
||||
- LOG_OUTPUT=stdout
|
||||
- 示例二:生产(结构化日志,集中化采集)
|
||||
- LOG_LEVEL=info
|
||||
- LOG_FORMAT=json
|
||||
- LOG_OUTPUT=stdout
|
||||
- 示例三:传统服务器(文件输出,配合轮转)
|
||||
- LOG_LEVEL=info
|
||||
- LOG_FORMAT=json
|
||||
- LOG_OUTPUT=/var/log/carrotskin/app.log
|
||||
- max_size=100
|
||||
- max_backups=3
|
||||
- max_age=28
|
||||
- compress=true
|
||||
- 最佳实践:
|
||||
- 生产环境统一使用 JSON 格式与 stdout,便于容器日志采集。
|
||||
- 严格控制日志级别,避免 debug 在生产长期开启。
|
||||
- 对关键路径增加结构化字段(如用户 ID、请求 ID),便于关联追踪。
|
||||
- 在中间件中统一记录请求上下文,确保异常时具备足够信息。
|
||||
- 如需文件轮转,建议在日志工厂中引入轮转库并使用上述配置项。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L170-L178)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L30-L41)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L30-L37)
|
||||
205
.qoder/repowiki/zh/content/配置管理/服务器配置.md
Normal file
205
.qoder/repowiki/zh/content/配置管理/服务器配置.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# 服务器配置
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [config.go](file://pkg/config/config.go)
|
||||
- [manager.go](file://pkg/config/manager.go)
|
||||
- [main.go](file://cmd/server/main.go)
|
||||
- [start.sh](file://start.sh)
|
||||
- [dev.sh](file://scripts/dev.sh)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [服务器配置项详解](#服务器配置项详解)
|
||||
3. [环境变量覆盖机制](#环境变量覆盖机制)
|
||||
4. [配置示例](#配置示例)
|
||||
5. [性能调优建议](#性能调优建议)
|
||||
6. [配置结构体说明](#配置结构体说明)
|
||||
|
||||
## 简介
|
||||
CarrotSkin项目采用基于环境变量的配置管理机制,通过Viper库实现灵活的配置加载与覆盖。服务器模块的配置主要集中在`ServerConfig`结构体中,定义了端口、运行模式、读写超时等关键参数。本文档详细说明这些配置项的作用、默认值以及如何通过环境变量进行覆盖,为开发者提供清晰的配置指导。
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L26-L32)
|
||||
- [main.go](file://cmd/server/main.go#L27-L124)
|
||||
|
||||
## 服务器配置项详解
|
||||
|
||||
### server.port
|
||||
- **作用**:指定服务器监听的端口号
|
||||
- **数据类型**:string
|
||||
- **默认值**:":8080"
|
||||
- **说明**:该配置值应包含冒号前缀,表示监听所有网络接口上的指定端口。例如":8080"表示监听8080端口。
|
||||
|
||||
### server.mode
|
||||
- **作用**:设置服务器运行模式
|
||||
- **数据类型**:string
|
||||
- **默认值**:"debug"
|
||||
- **说明**:支持"debug"和"production"两种模式。在生产模式下,Gin框架会自动切换到发布模式,关闭调试信息输出,提高性能和安全性。
|
||||
|
||||
### server.read_timeout
|
||||
- **作用**:设置HTTP服务器读取请求的超时时间
|
||||
- **数据类型**:time.Duration
|
||||
- **默认值**:"30s"
|
||||
- **说明**:防止客户端长时间不发送数据导致服务器资源被占用。超时后连接将被关闭。
|
||||
|
||||
### server.write_timeout
|
||||
- **作用**:设置HTTP服务器写入响应的超时时间
|
||||
- **数据类型**:time.Duration
|
||||
- **默认值**:"30s"
|
||||
- **说明**:防止响应过程过长占用服务器资源。对于大文件下载等长时间操作,可能需要适当增加此值。
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L137-L141)
|
||||
- [config.go](file://pkg/config/config.go#L26-L32)
|
||||
|
||||
## 环境变量覆盖机制
|
||||
|
||||
CarrotSkin项目支持通过环境变量覆盖默认配置,实现不同环境下的灵活配置管理。环境变量前缀为`CARROTSKIN`,具体映射关系如下:
|
||||
|
||||
| 配置项 | 环境变量 | 优先级 |
|
||||
|--------|----------|--------|
|
||||
| server.port | CARROTSKIN_SERVER_PORT | 高 |
|
||||
| server.mode | CARROTSKIN_SERVER_MODE | 高 |
|
||||
| server.read_timeout | CARROTSKIN_SERVER_READ_TIMEOUT | 高 |
|
||||
| server.write_timeout | CARROTSKIN_SERVER_WRITE_TIMEOUT | 高 |
|
||||
|
||||
配置加载流程:
|
||||
1. 加载`.env`文件中的环境变量
|
||||
2. 设置各项配置的默认值
|
||||
3. 绑定环境变量映射关系
|
||||
4. 从环境变量中读取并覆盖配置
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始] --> B[加载.env文件]
|
||||
B --> C[设置默认配置值]
|
||||
C --> D[绑定环境变量映射]
|
||||
D --> E[从环境变量覆盖配置]
|
||||
E --> F[返回配置实例]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.go](file://pkg/config/config.go#L108-L134)
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L192-L196)
|
||||
- [config.go](file://pkg/config/config.go#L108-L134)
|
||||
|
||||
## 配置示例
|
||||
|
||||
### 开发环境配置
|
||||
在开发环境中,通常使用默认配置或通过`dev.sh`脚本启动:
|
||||
|
||||
```bash
|
||||
# 启动开发服务器
|
||||
./scripts/dev.sh
|
||||
```
|
||||
|
||||
或者手动设置环境变量:
|
||||
```bash
|
||||
export CARROTSKIN_SERVER_PORT=":8080"
|
||||
export CARROTSKIN_SERVER_MODE="debug"
|
||||
export CARROTSKIN_SERVER_READ_TIMEOUT="30s"
|
||||
export CARROTSKIN_SERVER_WRITE_TIMEOUT="30s"
|
||||
go run ./cmd/server
|
||||
```
|
||||
|
||||
### 生产环境配置
|
||||
生产环境建议使用`start.sh`脚本,并设置更严格的配置:
|
||||
|
||||
```bash
|
||||
# 生产环境启动脚本示例
|
||||
export CARROTSKIN_SERVER_PORT=":80"
|
||||
export CARROTSKIN_SERVER_MODE="production"
|
||||
export CARROTSKIN_SERVER_READ_TIMEOUT="15s"
|
||||
export CARROTSKIN_SERVER_WRITE_TIMEOUT="15s"
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### Docker环境配置
|
||||
在Docker环境中,可以通过环境变量进行配置:
|
||||
|
||||
```dockerfile
|
||||
environment:
|
||||
- CARROTSKIN_SERVER_PORT=:80
|
||||
- CARROTSKIN_SERVER_MODE=production
|
||||
- CARROTSKIN_SERVER_READ_TIMEOUT=20s
|
||||
- CARROTSKIN_SERVER_WRITE_TIMEOUT=20s
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [start.sh](file://start.sh#L1-L37)
|
||||
- [dev.sh](file://scripts/dev.sh#L1-L29)
|
||||
|
||||
## 性能调优建议
|
||||
|
||||
### 高并发场景下的超时设置
|
||||
在高并发场景下,合理的超时设置对系统稳定性至关重要:
|
||||
|
||||
- **低延迟场景**:对于API服务等需要快速响应的场景,建议将读写超时设置为10-15秒
|
||||
- **大文件传输场景**:对于包含文件上传下载的功能,建议适当增加write_timeout至60秒以上
|
||||
- **内网服务**:如果是内网服务且网络环境稳定,可以将超时时间设置得更短,如5-10秒
|
||||
|
||||
### 连接池与超时的协同优化
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[客户端请求] --> B{连接建立}
|
||||
B --> |成功| C[读取请求]
|
||||
C --> D{读取超时}
|
||||
D --> |超时| E[关闭连接]
|
||||
D --> |成功| F[处理请求]
|
||||
F --> G[写入响应]
|
||||
G --> H{写入超时}
|
||||
H --> |超时| I[关闭连接]
|
||||
H --> |成功| J[完成响应]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [main.go](file://cmd/server/main.go#L93-L98)
|
||||
|
||||
**Section sources**
|
||||
- [main.go](file://cmd/server/main.go#L93-L98)
|
||||
- [config.go](file://pkg/config/config.go#L139-L140)
|
||||
|
||||
## 配置结构体说明
|
||||
|
||||
### ServerConfig 结构体
|
||||
```go
|
||||
type ServerConfig struct {
|
||||
Port string `mapstructure:"port"`
|
||||
Mode string `mapstructure:"mode"`
|
||||
ReadTimeout time.Duration `mapstructure:"read_timeout"`
|
||||
WriteTimeout time.Duration `mapstructure:"write_timeout"`
|
||||
}
|
||||
```
|
||||
|
||||
- **Port**:端口号,字符串类型,需包含冒号前缀
|
||||
- **Mode**:运行模式,可选值为"debug"或"production"
|
||||
- **ReadTimeout**:读取超时,time.Duration类型,支持"30s"、"1m"等格式
|
||||
- **WriteTimeout**:写入超时,time.Duration类型,支持"30s"、"1m"等格式
|
||||
|
||||
### 配置初始化流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as main.go
|
||||
participant Config as config.go
|
||||
participant Viper as Viper库
|
||||
Main->>Config : config.Init()
|
||||
Config->>Viper : 加载.env文件
|
||||
Viper-->>Config : 返回环境变量
|
||||
Config->>Config : setDefaults()
|
||||
Config->>Config : setupEnvMappings()
|
||||
Config->>Config : overrideFromEnv()
|
||||
Config-->>Main : 返回配置实例
|
||||
Main->>Main : 启动HTTP服务器
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.go](file://pkg/config/config.go#L108-L134)
|
||||
- [main.go](file://cmd/server/main.go#L27-L32)
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L26-L32)
|
||||
- [manager.go](file://pkg/config/manager.go#L19-L28)
|
||||
469
.qoder/repowiki/zh/content/配置管理/配置管理.md
Normal file
469
.qoder/repowiki/zh/content/配置管理/配置管理.md
Normal file
@@ -0,0 +1,469 @@
|
||||
# 配置管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [config.go](file://pkg/config/config.go)
|
||||
- [manager.go](file://pkg/config/manager.go)
|
||||
- [main.go](file://cmd/server/main.go)
|
||||
- [check-env.sh](file://scripts/check-env.sh)
|
||||
- [dev.sh](file://scripts/dev.sh)
|
||||
- [system_config.go](file://internal/model/system_config.go)
|
||||
- [rbac_model.conf](file://configs/casbin/rbac_model.conf)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [配置系统架构](#配置系统架构)
|
||||
3. [配置加载流程](#配置加载流程)
|
||||
4. [可配置选项详解](#可配置选项详解)
|
||||
5. [默认配置与覆盖机制](#默认配置与覆盖机制)
|
||||
6. [配置文件编写指南](#配置文件编写指南)
|
||||
7. [动态配置与环境特定配置](#动态配置与环境特定配置)
|
||||
8. [配置验证与最佳实践](#配置验证与最佳实践)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
CarrotSkin项目的配置管理系统采用Viper库实现,提供了一套完整的配置管理解决方案。该系统支持从环境变量、.env文件等多种来源加载配置,确保了应用在不同环境下的灵活性和可移植性。配置系统设计遵循了安全性和易用性的原则,为开发者提供了清晰的配置管理接口。
|
||||
|
||||
本系统的主要特点包括:
|
||||
- 基于Viper库的配置管理
|
||||
- 支持环境变量和.env文件
|
||||
- 线程安全的单例模式
|
||||
- 丰富的默认配置值
|
||||
- 灵活的配置覆盖机制
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [manager.go](file://pkg/config/manager.go#L1-L68)
|
||||
|
||||
## 配置系统架构
|
||||
|
||||
CarrotSkin的配置系统采用分层架构设计,核心组件包括配置结构体、配置管理器和配置加载器。系统通过Viper库实现配置的解析和管理,确保了配置的一致性和可靠性。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[环境变量] --> B[Viper配置管理器]
|
||||
C[.env文件] --> B
|
||||
B --> D[Config结构体]
|
||||
D --> E[ServerConfig]
|
||||
D --> F[DatabaseConfig]
|
||||
D --> G[RedisConfig]
|
||||
D --> H[RustFSConfig]
|
||||
D --> I[JWTConfig]
|
||||
D --> J[LogConfig]
|
||||
D --> K[UploadConfig]
|
||||
D --> L[EmailConfig]
|
||||
M[配置管理器] --> D
|
||||
M --> N[全局配置实例]
|
||||
O[应用程序] --> M
|
||||
style A fill:#f9f,stroke:#333
|
||||
style C fill:#f9f,stroke:#333
|
||||
style B fill:#bbf,stroke:#333
|
||||
style D fill:#ff9,stroke:#333
|
||||
style M fill:#9f9,stroke:#333
|
||||
style O fill:#f96,stroke:#333
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.go](file://pkg/config/config.go#L14-L24)
|
||||
- [manager.go](file://pkg/config/manager.go#L8-L17)
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [manager.go](file://pkg/config/manager.go#L1-L68)
|
||||
|
||||
## 配置加载流程
|
||||
|
||||
CarrotSkin的配置加载流程是一个多步骤的过程,确保配置能够正确地从各种来源加载并应用。加载流程包括环境变量前缀设置、默认值配置、环境变量映射和最终的配置解析。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> LoadDotEnv["加载.env文件"]
|
||||
LoadDotEnv --> SetDefaults["设置默认值"]
|
||||
SetDefaults --> SetPrefix["设置环境变量前缀 CARROTSKIN"]
|
||||
SetPrefix --> EnableAutoEnv["启用自动环境变量"]
|
||||
EnableAutoEnv --> SetupMappings["设置环境变量映射"]
|
||||
SetupMappings --> UnmarshalConfig["解析配置到结构体"]
|
||||
UnmarshalConfig --> OverrideEnv["从环境变量覆盖特殊配置"]
|
||||
OverrideEnv --> ReturnConfig["返回配置实例"]
|
||||
ReturnConfig --> End([结束])
|
||||
style Start fill:#4CAF50,stroke:#333
|
||||
style End fill:#4CAF50,stroke:#333
|
||||
style LoadDotEnv fill:#2196F3,stroke:#333
|
||||
style SetDefaults fill:#2196F3,stroke:#333
|
||||
style SetPrefix fill:#2196F3,stroke:#333
|
||||
style EnableAutoEnv fill:#2196F3,stroke:#333
|
||||
style SetupMappings fill:#2196F3,stroke:#333
|
||||
style UnmarshalConfig fill:#2196F3,stroke:#333
|
||||
style OverrideEnv fill:#2196F3,stroke:#333
|
||||
style ReturnConfig fill:#2196F3,stroke:#333
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.go](file://pkg/config/config.go#L108-L132)
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L108-L132)
|
||||
|
||||
## 可配置选项详解
|
||||
|
||||
CarrotSkin项目提供了丰富的可配置选项,涵盖了服务器、数据库、Redis、对象存储、JWT、日志、文件上传和邮件等多个模块。每个模块都有详细的配置参数,满足不同场景的需求。
|
||||
|
||||
### 服务器配置
|
||||
|
||||
服务器配置控制应用的基本运行参数,包括端口、模式和超时设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| server.port | SERVER_PORT | string | 服务器监听端口 | :8080 |
|
||||
| server.mode | SERVER_MODE | string | 运行模式 (debug/production) | debug |
|
||||
| server.read_timeout | SERVER_READ_TIMEOUT | duration | 读取超时时间 | 30s |
|
||||
| server.write_timeout | SERVER_WRITE_TIMEOUT | duration | 写入超时时间 | 30s |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L26-L32)
|
||||
|
||||
### 数据库配置
|
||||
|
||||
数据库配置管理与PostgreSQL数据库的连接参数和连接池设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| database.driver | DATABASE_DRIVER | string | 数据库驱动 | postgres |
|
||||
| database.host | DATABASE_HOST | string | 数据库主机地址 | localhost |
|
||||
| database.port | DATABASE_PORT | int | 数据库端口 | 5432 |
|
||||
| database.username | DATABASE_USERNAME | string | 数据库用户名 | - |
|
||||
| database.password | DATABASE_PASSWORD | string | 数据库密码 | - |
|
||||
| database.database | DATABASE_NAME | string | 数据库名称 | - |
|
||||
| database.ssl_mode | DATABASE_SSL_MODE | string | SSL模式 | disable |
|
||||
| database.timezone | DATABASE_TIMEZONE | string | 时区设置 | Asia/Shanghai |
|
||||
| database.max_idle_conns | DATABASE_MAX_IDLE_CONNS | int | 最大空闲连接数 | 10 |
|
||||
| database.max_open_conns | DATABASE_MAX_OPEN_CONNS | int | 最大打开连接数 | 100 |
|
||||
| database.conn_max_lifetime | DATABASE_CONN_MAX_LIFETIME | duration | 连接最大生命周期 | 1h |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L34-L47)
|
||||
|
||||
### Redis配置
|
||||
|
||||
Redis配置管理Redis缓存服务的连接信息和连接池设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| redis.host | REDIS_HOST | string | Redis主机地址 | localhost |
|
||||
| redis.port | REDIS_PORT | int | Redis端口 | 6379 |
|
||||
| redis.password | REDIS_PASSWORD | string | Redis密码 | - |
|
||||
| redis.database | REDIS_DATABASE | int | Redis数据库编号 | 0 |
|
||||
| redis.pool_size | REDIS_POOL_SIZE | int | 连接池大小 | 10 |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L49-L56)
|
||||
|
||||
### 对象存储(RustFS)配置
|
||||
|
||||
对象存储配置管理S3兼容的对象存储服务(RustFS)的连接信息和存储桶设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| rustfs.endpoint | RUSTFS_ENDPOINT | string | 对象存储端点 | 127.0.0.1:9000 |
|
||||
| rustfs.access_key | RUSTFS_ACCESS_KEY | string | 访问密钥 | - |
|
||||
| rustfs.secret_key | RUSTFS_SECRET_KEY | string | 密钥 | - |
|
||||
| rustfs.use_ssl | RUSTFS_USE_SSL | bool | 是否使用SSL | false |
|
||||
| rustfs.buckets | RUSTFS_BUCKET_* | map[string]string | 存储桶映射 | - |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L58-L65)
|
||||
|
||||
### JWT配置
|
||||
|
||||
JWT配置管理JSON Web Token的密钥和过期时间设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| jwt.secret | JWT_SECRET | string | JWT密钥 | - |
|
||||
| jwt.expire_hours | JWT_EXPIRE_HOURS | int | JWT过期小时数 | 168(7天) |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L67-L71)
|
||||
|
||||
### 日志配置
|
||||
|
||||
日志配置管理应用日志的级别、格式和文件滚动设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| log.level | LOG_LEVEL | string | 日志级别 | info |
|
||||
| log.format | LOG_FORMAT | string | 日志格式 | json |
|
||||
| log.output | LOG_OUTPUT | string | 日志输出路径 | logs/app.log |
|
||||
| log.max_size | LOG_MAX_SIZE | int | 单个日志文件最大大小(MB) | 100 |
|
||||
| log.max_backups | LOG_MAX_BACKUPS | int | 保留旧日志文件的最大个数 | 3 |
|
||||
| log.max_age | LOG_MAX_AGE | int | 保留旧日志文件的最大天数 | 28 |
|
||||
| log.compress | LOG_COMPRESS | bool | 是否压缩归档日志 | true |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L79-L88)
|
||||
|
||||
### 文件上传配置
|
||||
|
||||
文件上传配置管理文件上传的大小限制和允许的文件类型。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| upload.max_size | UPLOAD_MAX_SIZE | int64 | 最大上传文件大小 | 10MB |
|
||||
| upload.allowed_types | - | []string | 允许的文件MIME类型 | ["image/png", "image/jpeg"] |
|
||||
| upload.texture_max_size | UPLOAD_TEXTURE_MAX_SIZE | int64 | 纹理文件最大大小 | 2MB |
|
||||
| upload.avatar_max_size | UPLOAD_AVATAR_MAX_SIZE | int64 | 头像文件最大大小 | 1MB |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L90-L96)
|
||||
|
||||
### 邮件配置
|
||||
|
||||
邮件配置管理SMTP邮件服务的连接信息和发件人设置。
|
||||
|
||||
| 配置项 | 环境变量 | 类型 | 描述 | 默认值 |
|
||||
|--------|----------|------|------|--------|
|
||||
| email.enabled | EMAIL_ENABLED | bool | 是否启用邮件服务 | false |
|
||||
| email.smtp_host | EMAIL_SMTP_HOST | string | SMTP主机地址 | - |
|
||||
| email.smtp_port | EMAIL_SMTP_PORT | int | SMTP端口 | 587 |
|
||||
| email.username | EMAIL_USERNAME | string | SMTP用户名 | - |
|
||||
| email.password | EMAIL_PASSWORD | string | SMTP密码 | - |
|
||||
| email.from_name | EMAIL_FROM_NAME | string | 发件人名称 | - |
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L98-L106)
|
||||
|
||||
## 默认配置与覆盖机制
|
||||
|
||||
CarrotSkin的配置系统采用分层覆盖机制,确保配置的灵活性和可靠性。系统首先设置合理的默认值,然后通过环境变量进行覆盖,最后处理特殊的配置覆盖逻辑。
|
||||
|
||||
### 默认配置设置
|
||||
|
||||
系统通过`setDefaults()`函数设置所有配置项的默认值,确保在没有提供外部配置时应用仍能正常运行。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Config {
|
||||
+Server ServerConfig
|
||||
+Database DatabaseConfig
|
||||
+Redis RedisConfig
|
||||
+RustFS RustFSConfig
|
||||
+JWT JWTConfig
|
||||
+Casbin CasbinConfig
|
||||
+Log LogConfig
|
||||
+Upload UploadConfig
|
||||
+Email EmailConfig
|
||||
}
|
||||
class ServerConfig {
|
||||
+Port string
|
||||
+Mode string
|
||||
+ReadTimeout time.Duration
|
||||
+WriteTimeout time.Duration
|
||||
}
|
||||
class DatabaseConfig {
|
||||
+Driver string
|
||||
+Host string
|
||||
+Port int
|
||||
+Username string
|
||||
+Password string
|
||||
+Database string
|
||||
+SSLMode string
|
||||
+Timezone string
|
||||
+MaxIdleConns int
|
||||
+MaxOpenConns int
|
||||
+ConnMaxLifetime time.Duration
|
||||
}
|
||||
class RedisConfig {
|
||||
+Host string
|
||||
+Port int
|
||||
+Password string
|
||||
+Database int
|
||||
+PoolSize int
|
||||
}
|
||||
class RustFSConfig {
|
||||
+Endpoint string
|
||||
+AccessKey string
|
||||
+SecretKey string
|
||||
+UseSSL bool
|
||||
+Buckets map[string]string
|
||||
}
|
||||
class JWTConfig {
|
||||
+Secret string
|
||||
+ExpireHours int
|
||||
}
|
||||
class LogConfig {
|
||||
+Level string
|
||||
+Format string
|
||||
+Output string
|
||||
+MaxSize int
|
||||
+MaxBackups int
|
||||
+MaxAge int
|
||||
+Compress bool
|
||||
}
|
||||
Config "1" *-- "1" ServerConfig
|
||||
Config "1" *-- "1" DatabaseConfig
|
||||
Config "1" *-- "1" RedisConfig
|
||||
Config "1" *-- "1" RustFSConfig
|
||||
Config "1" *-- "1" JWTConfig
|
||||
Config "1" *-- "1" LogConfig
|
||||
Config "1" *-- "1" UploadConfig
|
||||
Config "1" *-- "1" EmailConfig
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.go](file://pkg/config/config.go#L13-L24)
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L135-L188)
|
||||
|
||||
### 配置覆盖流程
|
||||
|
||||
配置覆盖流程确保了配置的优先级顺序:环境变量 > .env文件 > 默认值。系统通过`overrideFromEnv()`函数处理特殊的配置覆盖逻辑。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 应用程序
|
||||
participant ConfigMgr as 配置管理器
|
||||
participant Viper as Viper库
|
||||
participant Env as 环境变量
|
||||
participant DotEnv as .env文件
|
||||
App->>ConfigMgr : 调用 config.Init()
|
||||
ConfigMgr->>ConfigMgr : 执行 once.Do()
|
||||
ConfigMgr->>DotEnv : 加载 .env 文件
|
||||
ConfigMgr->>Viper : 设置默认值
|
||||
ConfigMgr->>Viper : 设置环境变量前缀 CARROTSKIN
|
||||
ConfigMgr->>Viper : 启用自动环境变量
|
||||
ConfigMgr->>Viper : 绑定环境变量映射
|
||||
Viper->>Env : 读取环境变量
|
||||
Viper->>Viper : 解析配置到结构体
|
||||
ConfigMgr->>Env : 从环境变量覆盖特殊配置
|
||||
ConfigMgr->>App : 返回配置实例
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.go](file://pkg/config/config.go#L108-L132)
|
||||
- [config.go](file://pkg/config/config.go#L238-L304)
|
||||
|
||||
**Section sources**
|
||||
- [config.go](file://pkg/config/config.go#L238-L304)
|
||||
|
||||
## 配置文件编写指南
|
||||
|
||||
为帮助初学者快速上手,以下是配置文件的编写指南。
|
||||
|
||||
### .env文件示例
|
||||
|
||||
创建`.env`文件并填入以下内容:
|
||||
|
||||
```bash
|
||||
# 数据库配置
|
||||
DATABASE_HOST=localhost
|
||||
DATABASE_PORT=5432
|
||||
DATABASE_USERNAME=carrot
|
||||
DATABASE_PASSWORD=secret
|
||||
DATABASE_NAME=carrotskin
|
||||
DATABASE_SSL_MODE=disable
|
||||
|
||||
# 对象存储配置
|
||||
RUSTFS_ENDPOINT=127.0.0.1:9000
|
||||
RUSTFS_ACCESS_KEY=minioadmin
|
||||
RUSTFS_SECRET_KEY=minioadmin
|
||||
RUSTFS_USE_SSL=false
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET=your-jwt-secret-key-change-this-in-production
|
||||
|
||||
# 服务器配置
|
||||
SERVER_PORT=:8080
|
||||
SERVER_MODE=debug
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
```
|
||||
|
||||
### 配置验证脚本
|
||||
|
||||
使用提供的`check-env.sh`脚本验证配置的完整性:
|
||||
|
||||
```bash
|
||||
./scripts/check-env.sh
|
||||
```
|
||||
|
||||
该脚本会检查必需的环境变量是否设置,并提供配置概览和安全建议。
|
||||
|
||||
**Section sources**
|
||||
- [check-env.sh](file://scripts/check-env.sh#L1-L78)
|
||||
- [dev.sh](file://scripts/dev.sh#L1-L29)
|
||||
|
||||
## 动态配置与环境特定配置
|
||||
|
||||
对于经验丰富的开发者,CarrotSkin提供了动态配置和环境特定配置的最佳实践。
|
||||
|
||||
### 环境特定配置
|
||||
|
||||
通过环境变量前缀`CARROTSKIN`,可以在不同环境中使用不同的配置:
|
||||
|
||||
```bash
|
||||
# 开发环境
|
||||
CARROTSKIN_SERVER_PORT=:8080 \
|
||||
CARROTSKIN_DATABASE_HOST=localhost \
|
||||
CARROTSKIN_REDIS_HOST=localhost \
|
||||
go run cmd/server/main.go
|
||||
|
||||
# 生产环境
|
||||
CARROTSKIN_SERVER_PORT=:80 \
|
||||
CARROTSKIN_DATABASE_HOST=prod-db.example.com \
|
||||
CARROTSKIN_REDIS_HOST=prod-redis.example.com \
|
||||
go run cmd/server/main.go
|
||||
```
|
||||
|
||||
### 动态配置管理
|
||||
|
||||
系统提供了线程安全的配置访问接口,支持在运行时安全地获取配置:
|
||||
|
||||
```go
|
||||
// 获取配置实例
|
||||
cfg, err := config.GetConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("配置获取失败: %v", err)
|
||||
}
|
||||
|
||||
// 或使用panic方式获取(确保配置已初始化)
|
||||
cfg := config.MustGetConfig()
|
||||
|
||||
// 获取特定模块配置
|
||||
rustFSConfig := config.MustGetRustFSConfig()
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [manager.go](file://pkg/config/manager.go#L19-L63)
|
||||
- [main.go](file://cmd/server/main.go#L27-L124)
|
||||
|
||||
## 配置验证与最佳实践
|
||||
|
||||
### 配置验证
|
||||
|
||||
CarrotSkin提供了多种配置验证机制,确保配置的正确性和安全性:
|
||||
|
||||
1. **必需变量检查**:通过`check-env.sh`脚本检查必需的环境变量
|
||||
2. **配置合理性检查**:检查JWT密钥长度、数据库密码等安全相关配置
|
||||
3. **运行时验证**:在应用启动时验证配置的有效性
|
||||
|
||||
### 最佳实践
|
||||
|
||||
1. **使用.env文件管理开发配置**:避免将敏感信息硬编码在代码中
|
||||
2. **设置强密码和密钥**:确保JWT密钥至少32字符,使用随机字符串
|
||||
3. **环境隔离**:为不同环境(开发、测试、生产)使用不同的配置
|
||||
4. **配置备份**:定期备份重要的配置文件
|
||||
5. **监控配置变更**:记录配置变更历史,便于问题追踪
|
||||
|
||||
**Section sources**
|
||||
- [check-env.sh](file://scripts/check-env.sh#L1-L78)
|
||||
|
||||
## 结论
|
||||
|
||||
CarrotSkin的配置管理系统提供了一套完整、灵活且安全的配置管理解决方案。通过Viper库的强大功能,系统能够从多种来源加载配置,并提供了丰富的默认值和灵活的覆盖机制。配置系统的设计考虑了不同用户的需求,既为初学者提供了简单的配置文件编写指南,又为经验丰富的开发者提供了动态配置和环境特定配置的最佳实践。
|
||||
|
||||
该系统的线程安全设计和单例模式确保了配置的一致性和可靠性,而详细的配置选项和验证机制则保证了应用的稳定运行。通过遵循本文档提供的指南和最佳实践,开发者可以有效地管理和维护CarrotSkin应用的配置,确保其在不同环境下的正常运行。
|
||||
Reference in New Issue
Block a user