Files
go-common/docs/config.md
2026-01-30 21:40:21 +08:00

563 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 配置工具文档
## 概述
配置工具提供了从外部文件加载和管理应用配置的功能支持数据库、LocalStorage、OSS、Redis、CORS、MinIO、邮件、短信等常用服务的配置。
## 功能特性
- 支持从外部JSON文件加载配置
- 支持数据库配置MySQL、PostgreSQL、SQLite
- 支持本地存储配置LocalStorage文件上传保存到本地文件夹
- 支持OSS对象存储配置阿里云、腾讯云、AWS、七牛云等
- 支持Redis配置
- 支持CORS配置与middleware包集成
- 支持MinIO配置
- 支持邮件配置SMTP
- 支持短信配置(阿里云短信)
- 自动设置默认值
- 自动生成数据库连接字符串DSN
- 自动生成Redis地址
## 配置文件格式
配置文件采用JSON格式支持以下配置项
```json
{
"database": {
"type": "mysql",
"host": "localhost",
"port": 3306,
"user": "root",
"password": "password",
"database": "testdb",
"charset": "utf8mb4",
"maxOpenConns": 100,
"maxIdleConns": 10,
"connMaxLifetime": 3600
},
"oss": {
"provider": "aliyun",
"endpoint": "oss-cn-hangzhou.aliyuncs.com",
"accessKeyId": "your-access-key-id",
"accessKeySecret": "your-access-key-secret",
"bucket": "your-bucket-name",
"region": "cn-hangzhou",
"useSSL": true,
"domain": "https://cdn.example.com"
},
"redis": {
"host": "localhost",
"port": 6379,
"password": "",
"database": 0,
"maxRetries": 3,
"poolSize": 10,
"minIdleConns": 5,
"dialTimeout": 5,
"readTimeout": 3,
"writeTimeout": 3
},
"cors": {
"allowedOrigins": ["*"],
"allowedMethods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"allowedHeaders": ["Content-Type", "Authorization", "X-Requested-With", "X-Timezone"],
"exposedHeaders": [],
"allowCredentials": false,
"maxAge": 86400
},
"minio": {
"endpoint": "localhost:9000",
"accessKeyId": "minioadmin",
"secretAccessKey": "minioadmin",
"useSSL": false,
"bucket": "test-bucket",
"region": "us-east-1",
"domain": "http://localhost:9000"
},
"localStorage": {
"baseDir": "./uploads",
"publicURL": "http://localhost:8080/file?key={objectKey}"
},
"email": {
"host": "smtp.example.com",
"port": 587,
"username": "your-email@example.com",
"password": "your-email-password",
"from": "your-email@example.com",
"fromName": "Your App Name",
"useTLS": true,
"useSSL": false,
"timeout": 30
},
"sms": {
"accessKeyId": "your-aliyun-access-key-id",
"accessKeySecret": "your-aliyun-access-key-secret",
"region": "cn-hangzhou",
"signName": "Your Sign Name",
"templateCode": "SMS_123456789",
"endpoint": "",
"timeout": 10
}
}
```
## 使用方法
### 1. 加载配置文件
```go
import "git.toowon.com/jimmy/go-common/config"
// 从文件加载配置(支持绝对路径和相对路径)
config, err := config.LoadFromFile("/path/to/config.json")
if err != nil {
log.Fatal(err)
}
// 或者从字节数组加载
data := []byte(`{"database": {...}}`)
config, err := config.LoadFromBytes(data)
```
### 2. 获取数据库配置
```go
// 获取数据库配置对象
dbConfig := config.GetDatabase()
if dbConfig != nil {
fmt.Printf("Database: %s@%s:%d/%s\n",
dbConfig.User, dbConfig.Host, dbConfig.Port, dbConfig.Database)
}
// 获取数据库连接字符串DSN
dsn, err := config.GetDatabaseDSN()
if err != nil {
log.Fatal(err)
}
// MySQL: "root:password@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True&loc=UTC"
// PostgreSQL: "host=localhost port=5432 user=root password=password dbname=testdb timezone=UTC sslmode=disable"
// 注意数据库时间统一使用UTC时间
```
### 3. 获取OSS配置
```go
ossConfig := config.GetOSS()
if ossConfig != nil {
fmt.Printf("OSS Provider: %s\n", ossConfig.Provider)
fmt.Printf("Endpoint: %s\n", ossConfig.Endpoint)
fmt.Printf("Bucket: %s\n", ossConfig.Bucket)
}
```
### 4. 获取Redis配置
```go
redisConfig := config.GetRedis()
if redisConfig != nil {
fmt.Printf("Redis: %s:%d\n", redisConfig.Host, redisConfig.Port)
}
// 获取Redis地址格式: host:port
addr := config.GetRedisAddr()
// 输出: "localhost:6379"
```
### 5. 获取CORS配置
```go
// 获取CORS配置返回config.CORSConfig类型
configCORS := config.GetCORS()
// 转换为middleware.CORSConfig并使用CORS中间件
import "git.toowon.com/jimmy/go-common/middleware"
var middlewareCORS *middleware.CORSConfig
if configCORS != nil {
middlewareCORS = middleware.NewCORSConfig(
configCORS.AllowedOrigins,
configCORS.AllowedMethods,
configCORS.AllowedHeaders,
configCORS.ExposedHeaders,
configCORS.AllowCredentials,
configCORS.MaxAge,
)
}
chain := middleware.NewChain(
middleware.CORS(middlewareCORS),
)
```
### 6. 获取MinIO配置
```go
minioConfig := config.GetMinIO()
if minioConfig != nil {
fmt.Printf("MinIO Endpoint: %s\n", minioConfig.Endpoint)
fmt.Printf("Bucket: %s\n", minioConfig.Bucket)
}
```
### 6.1 获取本地存储配置LocalStorage
```go
localCfg := config.GetLocalStorage()
if localCfg != nil {
fmt.Printf("Local baseDir: %s\n", localCfg.BaseDir)
fmt.Printf("Local publicURL: %s\n", localCfg.PublicURL)
}
```
## 配置项说明
### DatabaseConfig 数据库配置
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| Type | string | 数据库类型: mysql, postgres, sqlite | - |
| Host | string | 数据库主机 | - |
| Port | int | 数据库端口 | - |
| User | string | 数据库用户名 | - |
| Password | string | 数据库密码 | - |
| Database | string | 数据库名称 | - |
| Charset | string | 字符集MySQL使用 | utf8mb4 |
| MaxOpenConns | int | 最大打开连接数 | 100 |
| MaxIdleConns | int | 最大空闲连接数 | 10 |
| ConnMaxLifetime | int | 连接最大生存时间(秒) | 3600 |
| DSN | string | 数据库连接字符串(如果设置,优先使用) | - |
### OSSConfig OSS配置
| 字段 | 类型 | 说明 |
|------|------|------|
| Provider | string | 提供商: aliyun, tencent, aws, qiniu |
| Endpoint | string | 端点地址 |
| AccessKeyID | string | 访问密钥ID |
| AccessKeySecret | string | 访问密钥 |
| Bucket | string | 存储桶名称 |
| Region | string | 区域 |
| UseSSL | bool | 是否使用SSL |
| Domain | string | 自定义域名CDN域名 |
### RedisConfig Redis配置
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| Host | string | Redis主机 | - |
| Port | int | Redis端口 | 6379 |
| Password | string | Redis密码 | - |
| Database | int | Redis数据库编号 | 0 |
| MaxRetries | int | 最大重试次数 | 3 |
| PoolSize | int | 连接池大小 | 10 |
| MinIdleConns | int | 最小空闲连接数 | 5 |
| DialTimeout | int | 连接超时时间(秒) | 5 |
| ReadTimeout | int | 读取超时时间(秒) | 3 |
| WriteTimeout | int | 写入超时时间(秒) | 3 |
| Addr | string | Redis地址如果设置优先使用 | - |
### CORSConfig CORS配置
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| AllowedOrigins | []string | 允许的源 | ["*"] |
| AllowedMethods | []string | 允许的HTTP方法 | ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"] |
| AllowedHeaders | []string | 允许的请求头 | ["Content-Type", "Authorization", "X-Requested-With", "X-Timezone"] |
| ExposedHeaders | []string | 暴露给客户端的响应头 | [] |
| AllowCredentials | bool | 是否允许发送凭证 | false |
| MaxAge | int | 预检请求的缓存时间(秒) | 86400 |
### MinIOConfig MinIO配置
| 字段 | 类型 | 说明 |
|------|------|------|
| Endpoint | string | MinIO端点地址 |
| AccessKeyID | string | 访问密钥ID |
| SecretAccessKey | string | 密钥 |
| UseSSL | bool | 是否使用SSL |
| Bucket | string | 存储桶名称 |
| Region | string | 区域 |
| Domain | string | 自定义域名 |
### LocalStorageConfig 本地存储配置
| 字段 | 类型 | 说明 |
|------|------|------|
| BaseDir | string | 本地文件保存根目录(必填) |
| PublicURL | string | 对外访问 URL可选。包含 `{objectKey}` 占位符时会替换为 `url.QueryEscape(objectKey)`;不包含时作为 URL 前缀拼接 |
### EmailConfig 邮件配置
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| Host | string | SMTP服务器地址 | - |
| Port | int | SMTP服务器端口 | 587 |
| Username | string | 发件人邮箱 | - |
| Password | string | 邮箱密码或授权码 | - |
| From | string | 发件人邮箱地址如果为空使用Username | Username |
| FromName | string | 发件人名称 | - |
| UseTLS | bool | 是否使用TLS | false |
| UseSSL | bool | 是否使用SSL | false |
| Timeout | int | 连接超时时间(秒) | 30 |
### SMSConfig 短信配置(阿里云短信)
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| AccessKeyID | string | 阿里云AccessKey ID | - |
| AccessKeySecret | string | 阿里云AccessKey Secret | - |
| Region | string | 区域cn-hangzhou | cn-hangzhou |
| SignName | string | 短信签名 | - |
| TemplateCode | string | 短信模板代码 | - |
| Endpoint | string | 服务端点(可选,默认使用区域端点) | - |
| Timeout | int | 请求超时时间(秒) | 10 |
### LoggerConfig 日志配置
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| Level | string | 日志级别: debug, info, warn, error | info |
| Output | string | 输出方式: stdout, stderr, file, both | stdout |
| FilePath | string | 日志文件路径当output为file或both时必需 | - |
| Prefix | string | 日志前缀 | - |
| DisableTimestamp | bool | 禁用时间戳 | false |
## 完整示例
### 示例1加载配置并使用
```go
package main
import (
"log"
"git.toowon.com/jimmy/go-common/config"
"git.toowon.com/jimmy/go-common/middleware"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
// 加载配置
cfg, err := config.LoadFromFile("./config.json")
if err != nil {
log.Fatal(err)
}
// 使用数据库配置
dsn, err := cfg.GetDatabaseDSN()
if err != nil {
log.Fatal(err)
}
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
// 使用Redis配置
redisAddr := cfg.GetRedisAddr()
fmt.Printf("Redis Address: %s\n", redisAddr)
// 使用CORS配置
configCORS := cfg.GetCORS()
var middlewareCORS *middleware.CORSConfig
if configCORS != nil {
middlewareCORS = middleware.NewCORSConfig(
configCORS.AllowedOrigins,
configCORS.AllowedMethods,
configCORS.AllowedHeaders,
configCORS.ExposedHeaders,
configCORS.AllowCredentials,
configCORS.MaxAge,
)
}
chain := middleware.NewChain(
middleware.CORS(middlewareCORS),
)
// 使用OSS配置
ossConfig := cfg.GetOSS()
if ossConfig != nil {
fmt.Printf("OSS Provider: %s\n", ossConfig.Provider)
}
// 使用MinIO配置
minioConfig := cfg.GetMinIO()
if minioConfig != nil {
fmt.Printf("MinIO Endpoint: %s\n", minioConfig.Endpoint)
}
}
```
### 示例2部分配置
配置文件可以只包含需要的配置项:
```json
{
"database": {
"type": "mysql",
"host": "localhost",
"port": 3306,
"user": "root",
"password": "password",
"database": "testdb"
},
"redis": {
"host": "localhost",
"port": 6379
}
}
```
未配置的部分会返回nil需要在使用前检查
```go
cfg, _ := config.LoadFromFile("./config.json")
dbConfig := cfg.GetDatabase()
if dbConfig != nil {
// 使用数据库配置
}
ossConfig := cfg.GetOSS()
if ossConfig == nil {
// OSS未配置
}
```
### 示例3使用DSN字段
如果配置文件中直接提供了DSN会优先使用
```json
{
"database": {
"type": "mysql",
"dsn": "root:password@tcp(localhost:3306)/testdb?charset=utf8mb4&parseTime=True"
}
}
```
```go
dsn, err := cfg.GetDatabaseDSN()
// 直接返回配置中的DSN不会重新构建
```
## API 参考
### LoadFromFile(filePath string) (*Config, error)
从文件加载配置。
**参数:**
- `filePath`: 配置文件路径(支持绝对路径和相对路径)
**返回:** 配置对象和错误信息
### LoadFromBytes(data []byte) (*Config, error)
从字节数组加载配置。
**参数:**
- `data`: JSON格式的配置数据
**返回:** 配置对象和错误信息
### (c *Config) GetDatabase() *DatabaseConfig
获取数据库配置。
**返回:** 数据库配置对象可能为nil
### (c *Config) GetDatabaseDSN() (string, error)
获取数据库连接字符串。
**返回:** DSN字符串和错误信息
### (c *Config) GetOSS() *OSSConfig
获取OSS配置。
**返回:** OSS配置对象可能为nil
### (c *Config) GetRedis() *RedisConfig
获取Redis配置。
**返回:** Redis配置对象可能为nil
### (c *Config) GetRedisAddr() string
获取Redis地址格式: host:port
**返回:** Redis地址字符串
### (c *Config) GetCORS() *middleware.CORSConfig
获取CORS配置并转换为middleware.CORSConfig类型。
**返回:** CORS配置对象如果配置为nil返回默认配置
### (c *Config) GetMinIO() *MinIOConfig
获取MinIO配置。
**返回:** MinIO配置对象可能为nil
### (c *Config) GetEmail() *EmailConfig
获取邮件配置。
**返回:** 邮件配置对象可能为nil
### (c *Config) GetSMS() *SMSConfig
获取短信配置。
**返回:** 短信配置对象可能为nil
### (c *Config) GetLogger() *LoggerConfig
获取日志配置。
**返回:** 日志配置对象可能为nil
## 注意事项
1. **配置文件路径**
- 支持绝对路径和相对路径
- 相对路径基于当前工作目录
2. **默认值**
- 配置加载时会自动设置默认值
- 如果配置项为nil对应的Get方法会返回nil
3. **DSN优先级**
- 如果配置中设置了DSN字段会优先使用
- 否则会根据配置项自动构建DSN
4. **配置验证**
- 当前版本不进行配置验证,请确保配置正确
- 建议在生产环境中添加配置验证逻辑
5. **安全性**
- 配置文件可能包含敏感信息(密码、密钥等)
- 建议将配置文件放在安全的位置,不要提交到版本控制系统
- 可以使用环境变量或配置管理服务
6. **数据库时区**
- 数据库时间统一使用UTC时间存储
- DSN中会自动设置UTC时区MySQL: loc=UTC, PostgreSQL: timezone=UTC
- 时区转换应在应用层处理使用datetime工具包进行时区转换
## 配置文件示例
完整配置文件示例请参考 `config/example.json`