配置管理¶
1. 模块定位¶
1.1 核心作用¶
配置管理模块负责统一管理系统的所有配置项,包括服务器端口、渠道凭证、日志级别等,提供灵活的配置来源和优先级机制。
一句话定义:配置管理模块是系统的"设置中心",统一管理所有可配置项。
1.2 设计目标¶
| 目标 | 说明 |
|---|---|
| 多来源支持 | 支持配置文件、环境变量、命令行参数 |
| 优先级机制 | 明确的配置覆盖优先级 |
| 类型安全 | 配置项有明确的类型定义 |
| 易于扩展 | 新增配置项简单直接 |
1.3 配置范围¶
graph TB
subgraph "配置管理范围"
subgraph "服务器配置"
S1[HTTP 端口]
S2[WebSocket 端口]
S3[Webhook 路径]
end
subgraph "渠道配置"
C1[微信 Token]
C2[钉钉 AppKey]
C3[飞书 AppID]
end
subgraph "运行配置"
R1[日志级别]
R2[调试模式]
end
end
2. 设计决策¶
2.1 为什么需要配置优先级?¶
问题背景: - 开发环境和生产环境配置不同 - 敏感信息不应写入配置文件 - 临时调试需要快速修改配置
优先级设计:
graph TB
subgraph "优先级(从高到低)"
P1[命令行参数
最高优先级]
P2[环境变量]
P3[配置文件]
P4[默认值
最低优先级]
end
P1 --> P2 --> P3 --> P4
理由: 1. 命令行参数:临时调试最方便 2. 环境变量:容器化部署的标准方式 3. 配置文件:持久化配置,版本控制 4. 默认值:开箱即用
2.2 为什么使用结构体而非 map?¶
决策:配置使用结构体定义,而非 map[string]interface{}。
graph TB
subgraph "结构体方式 ✅"
A1["type Config struct {
Port int
Token string
}"]
A2["类型安全
IDE 自动补全
编译时检查"]
end
subgraph "Map 方式 ❌"
B1["config['port'] = 8080"]
B2["运行时错误
无类型提示
难以维护"]
end
style A1 fill:#9f9
理由: 1. 类型安全:编译时检查类型错误 2. IDE 支持:自动补全和跳转 3. 文档化:结构体即文档
2.3 为什么敏感配置只通过环境变量?¶
决策:Token、Secret 等敏感配置只支持环境变量,不支持配置文件。
graph LR
subgraph "敏感配置"
T1[微信 Token]
T2[钉钉 AppSecret]
T3[飞书 AppSecret]
end
subgraph "来源"
EV[环境变量 ✅]
CF[配置文件 ❌]
end
T1 --> EV
T2 --> EV
T3 --> EV
style CF fill:#f99
理由: 1. 安全:避免敏感信息提交到版本控制 2. 合规:符合安全最佳实践 3. 简单:无需复杂的加密机制
3. 配置结构定义¶
3.1 主配置结构¶
// Config 主配置结构
type Config struct {
Server ServerConfig `json:"server"` // 服务器配置
Channels ChannelsConfig `json:"channels"` // 渠道配置
Log LogConfig `json:"log"` // 日志配置
}
// ServerConfig 服务器配置
type ServerConfig struct {
HTTPPort int `json:"http_port"` // HTTP 服务端口
WSPort int `json:"ws_port"` // WebSocket 服务端口
WebhookPath string `json:"webhook_path"` // Webhook 路径前缀
ReadTimeout int `json:"read_timeout"` // 读超时(秒)
WriteTimeout int `json:"write_timeout"` // 写超时(秒)
}
// ChannelsConfig 渠道配置集合
type ChannelsConfig struct {
WeChat WeChatConfig `json:"wechat"` // 微信配置
DingTalk DingTalkConfig `json:"dingtalk"` // 钉钉配置
Feishu FeishuConfig `json:"feishu"` // 飞书配置
}
// LogConfig 日志配置
type LogConfig struct {
Level string `json:"level"` // 日志级别
Format string `json:"format"` // 输出格式
Output string `json:"output"` // 输出目标
}
3.2 渠道配置结构¶
// WeChatConfig 微信配置
type WeChatConfig struct {
Enabled bool `json:"enabled"` // 是否启用
Token string `json:"-"` // 验证 Token(仅环境变量)
AppID string `json:"app_id"` // AppID
Secret string `json:"-"` // AppSecret(仅环境变量)
}
// DingTalkConfig 钉钉配置
type DingTalkConfig struct {
Enabled bool `json:"enabled"` // 是否启用
AppKey string `json:"app_key"` // AppKey
AppSecret string `json:"-"` // AppSecret(仅环境变量)
}
// FeishuConfig 飞书配置
type FeishuConfig struct {
Enabled bool `json:"enabled"` // 是否启用
AppID string `json:"app_id"` // AppID
AppSecret string `json:"-"` // AppSecret(仅环境变量)
}
4. 配置来源设计¶
4.1 配置来源优先级¶
sequenceDiagram
participant CLI as 命令行参数
participant ENV as 环境变量
participant FILE as 配置文件
participant DEF as 默认值
CLI->>ENV: 未设置则检查
ENV->>FILE: 未设置则检查
FILE->>DEF: 未设置则使用默认值
4.2 环境变量映射¶
| 配置项 | 环境变量 |
|---|---|
Server.HTTPPort |
GORT_HTTP_PORT |
Server.WSPort |
GORT_WS_PORT |
Channels.WeChat.Token |
GORT_WECHAT_TOKEN |
Channels.WeChat.Secret |
GORT_WECHAT_SECRET |
Channels.DingTalk.AppSecret |
GORT_DINGTALK_SECRET |
Log.Level |
GORT_LOG_LEVEL |
4.3 配置文件格式¶
支持 JSON 和 YAML 两种格式:
JSON 格式 (config.json):
{
"server": {
"http_port": 8080,
"ws_port": 8081,
"webhook_path": "/webhook"
},
"channels": {
"wechat": {
"enabled": true,
"app_id": "wx123456"
}
},
"log": {
"level": "info",
"format": "text"
}
}
YAML 格式 (config.yaml):
server:
http_port: 8080
ws_port: 8081
webhook_path: /webhook
channels:
wechat:
enabled: true
app_id: wx123456
log:
level: info
format: text
5. 默认值设计¶
5.1 默认配置¶
| 配置项 | 默认值 | 说明 |
|---|---|---|
Server.HTTPPort |
8080 | HTTP 服务端口 |
Server.WSPort |
8081 | WebSocket 服务端口 |
Server.WebhookPath |
/webhook |
Webhook 路径前缀 |
Server.ReadTimeout |
30 | 读超时(秒) |
Server.WriteTimeout |
30 | 写超时(秒) |
Log.Level |
info |
日志级别 |
Log.Format |
text |
日志格式 |
5.2 默认值设置方式¶
graph LR
A[定义默认值] --> B[加载配置文件]
B --> C[加载环境变量]
C --> D[加载命令行参数]
D --> E[最终配置]
6. 配置加载流程¶
6.1 加载流程¶
flowchart TB
Start[开始] --> CheckFile{配置文件存在?}
CheckFile -->|是| LoadFile[加载配置文件]
CheckFile -->|否| UseDefault[使用默认值]
LoadFile --> MergeDefault[合并默认值]
UseDefault --> LoadEnv
MergeDefault --> LoadEnv[加载环境变量]
LoadEnv --> LoadCLI[加载命令行参数]
LoadCLI --> Validate[验证配置]
Validate -->|有效| Done[返回配置]
Validate -->|无效| Error[返回错误]
6.2 配置验证¶
| 验证项 | 规则 |
|---|---|
| 端口号 | 1-65535 |
| Webhook 路径 | 以 / 开头 |
| 启用的渠道 | 必须配置必要凭证 |
| 日志级别 | debug/info/warn/error |
7. 与其他模块的关系¶
7.1 依赖关系¶
graph TB
subgraph "配置管理"
CFG[Config]
LOADER[Loader]
end
GW[Gateway] --> CFG
CH[Channel] --> CFG
LOG[Logger] --> CFG
LOADER --> CFG
style CFG fill:#9f9
7.2 使用方式¶
| 模块 | 使用的配置 |
|---|---|
| Gateway | Server 配置 |
| Channel | 渠道凭证配置 |
| Logger | Log 配置 |
8. 约束与限制¶
8.1 配置约束¶
| 约束 | 说明 |
|---|---|
敏感字段使用 json:"-" |
不序列化到配置文件 |
| 端口必须有效 | 1-65535 范围内 |
| 启用的渠道必须配置凭证 | 否则启动失败 |
8.2 环境变量约束¶
| 约束 | 说明 |
|---|---|
使用 GORT_ 前缀 |
避免与其他系统冲突 |
| 层级用下划线分隔 | 如 GORT_SERVER_HTTP_PORT |
9. 使用场景¶
9.1 开发环境¶
graph LR
subgraph "开发环境配置"
D1[配置文件: config.dev.yaml]
D2[日志级别: debug]
D3[端口: 8080/8081]
end
9.2 生产环境¶
graph LR
subgraph "生产环境配置"
P1[配置文件: config.prod.yaml]
P2[环境变量: 敏感凭证]
P3[日志级别: info]
end
9.3 Docker 部署¶
graph LR
subgraph "Docker 配置"
D1[配置文件: 挂载 Volume]
D2[环境变量: docker run -e]
D3[敏感信息: Docker Secrets]
end
10. 相关文档¶
- 01-gateway.md - Gateway 模块设计
- 02-channel.md - Channel 模块设计