6.2 KiB
6.2 KiB
tags, create time
| tags | create time | ||||||
|---|---|---|---|---|---|---|---|
|
2026-06-03 11:10 |
15. 配置级联机制
概述
Viper 三层配置级联 — YAML 文件 -> 环境变量 -> 默认值,一处配置随处运行。
正文
配置加载流程
flowchart LR
subgraph "配置源(优先级从低到高)"
D["默认值\nsetDefaults()"]
Y["YAML 文件\nconfig.yaml"]
E["环境变量\n.env / system env"]
end
subgraph "Viper 引擎"
V["Viper\n合并 + 覆盖"]
end
subgraph "输出"
C["Config Struct\n全局配置对象"]
S["各组件\nServer / DB / Redis / ..."]
end
D -->|"1. 设置默认值"| V
Y -->|"2. 读取 YAML"| V
E -->|"3. 绑定 ENV"| V
V -->|"Unmarshal"| C
C -->|"注入"| S
style D fill:#9e9e9e,stroke:#333,color:#fff
style Y fill:#2196f3,stroke:#333,color:#fff
style E fill:#f44336,stroke:#333,color:#fff
style V fill:#ff9800,stroke:#333,color:#fff
优先级规则:ENV > YAML > Default
环境变量始终拥有最高优先级,可以覆盖任何 YAML 配置;YAML 配置覆盖默认值。
配置结构体
type Config struct {
Server ServerConfig // HTTP 服务
Database DatabaseConfig // MySQL 数据库
JWT JWTConfig // JWT 签名
Log LogConfig // 日志
Redis RedisConfig // Redis 缓存
LLM LLMConfig // 大语言模型
ImageGen ImageGenConfig // 文生图 API
Qiniu QiniuConfig // 七牛云存储
WorkerPool WorkerPoolConfig // 协程池
TaskQueue TaskQueueConfig // 任务队列
}
| 配置块 | 关键字段 | 默认值 |
|---|---|---|
Server |
port, mode |
8080, debug |
Database |
dsn |
gen2d:password@tcp(127.0.0.1:3306)/gen2d |
JWT |
secret, expire |
gen2d-dev-secret, 7200s |
Log |
level, format |
info, text |
Redis |
addr, password, db |
localhost:6379, "", 0 |
LLM |
base_url, api_key, model |
api.openai.com/v1, "", gpt-4o |
ImageGen |
base_url, model, timeout |
api.suchuang.vip/v1, gpt-image-2-token, 120s |
Qiniu |
bucket, cdn_host, url_expire |
"", "", 3600s |
WorkerPool |
workers, queue_size, max_per_user |
NumCPU*4, 100, 2 |
TaskQueue |
driver, memory.buffer_size |
memory, 100 |
环境变量绑定
每个配置字段都有对应的环境变量绑定,命名规则为 GEN2D_ 前缀 + 大写下划线格式:
func bindEnvVars(v *viper.Viper) {
v.BindEnv("server.port", "GEN2D_PORT")
v.BindEnv("server.mode", "GEN2D_MODE")
v.BindEnv("database.dsn", "GEN2D_DSN")
v.BindEnv("jwt.secret", "GEN2D_JWT_SECRET")
v.BindEnv("llm.api_key", "GEN2D_LLM_API_KEY")
v.BindEnv("redis.addr", "GEN2D_REDIS_ADDR")
v.BindEnv("qiniu.access_key", "GEN2D_QINIU_ACCESS_KEY")
// ... 共 25+ 个绑定
}
| 配置路径 | 环境变量 | 说明 |
|---|---|---|
server.port |
GEN2D_PORT |
HTTP 端口 |
server.mode |
GEN2D_MODE |
debug / release |
database.dsn |
GEN2D_DSN |
MySQL 连接串 |
jwt.secret |
GEN2D_JWT_SECRET |
JWT 签名密钥 |
llm.base_url |
GEN2D_LLM_BASE_URL |
LLM API 地址 |
llm.api_key |
GEN2D_LLM_API_KEY |
LLM API 密钥 |
image_gen.base_url |
GEN2D_IMAGE_BASE_URL |
文生图 API 地址 |
redis.addr |
GEN2D_REDIS_ADDR |
Redis 地址 |
taskqueue.driver |
GEN2D_TASKQUEUE_DRIVER |
memory / rabbitmq |
使用场景
flowchart TD
subgraph "开发环境"
D1["config.yaml\n本地配置文件"]
D2[".env\n环境变量覆盖敏感值"]
D3["默认值\n开箱即用"]
end
subgraph "测试环境"
T1["环境变量\nCI/CD 管线注入"]
T2["默认值\n兜底"]
end
subgraph "生产环境"
P1["K8s ConfigMap\n非敏感配置"]
P2["K8s Secret\n敏感配置(密钥、DSN)"]
P3["默认值\n兜底"]
end
D1 --> D3
D2 --> D1
T1 --> T2
P1 --> P3
P2 --> P1
| 环境 | 主配置源 | 敏感配置 | 说明 |
|---|---|---|---|
| 开发 | config.yaml |
.env 文件 |
直观、可版本控制 |
| 测试 | 环境变量 | 环境变量 | CI/CD 管线注入 |
| 生产 | ConfigMap | Secret | K8s 原生管理 |
加载过程详解
sequenceDiagram
participant Main as main.go
participant Viper as Viper
participant YAML as config.yaml
participant ENV as 环境变量
participant Cfg as Config Struct
Main->>Viper: Load()
Main->>Viper: setDefaults(v)
Note over Viper: 设置 25+ 默认值
Viper->>YAML: ReadInConfig()
YAML-->>Viper: 配置内容
Viper->>Viper: bindEnvVars(v)
Note over Viper: 绑定 25+ 环境变量
Viper->>ENV: 读取环境变量
ENV-->>Viper: 覆盖对应字段
Viper->>Cfg: Unmarshal(&cfg)
Cfg-->>Main: 返回完整配置
关键步骤:
- 加载
.env文件 —godotenv.Load()从项目根目录读取.env - 设置默认值 —
setDefaults(v)为所有字段提供合理的默认值 - 读取 YAML —
v.ReadInConfig()从internal/config/config.yaml加载 - 绑定环境变量 —
bindEnvVars(v)将每个字段映射到GEN2D_*环境变量 - 反序列化 —
v.Unmarshal(&cfg)将合并后的配置映射到 Go 结构体
容错设计:YAML 文件不存在时不报错,仅使用环境变量 + 默认值。这确保了零配置即可启动。
与部署的关系
配置级联机制与部署架构紧密配合:
| 部署方式 | 配置策略 | 示例 |
|---|---|---|
go run 本地开发 |
YAML + .env |
config.yaml 配置 DB,.env 配置 API Key |
docker compose |
.env 文件注入 |
env_file: ./backend/.env |
| Kubernetes | ConfigMap + Secret | GEN2D_DSN 从 Secret 注入 |