跳转至

配置管理

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. 相关文档