-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
awesomeIt's awesome! We keep watching.It's awesome! We keep watching.discussWe need discuss to make decision.We need discuss to make decision.feature
Description
背景
12-Factor App 推荐的配置优先级(从高到低):
命令行参数 > 环境变量 > 配置文件 > 默认值
这也是 Spring Boot、Viper 等主流框架采用的方式。高优先级的配置源可以覆盖低优先级的值,便于运维在部署时通过环境变量或命令行参数覆盖配置,而无需修改配置文件。
现状问题
当前 gcfg 提供的方法:
| 方法 | 优先级 |
|---|---|
Get |
仅配置文件 |
GetWithEnv |
配置文件 > 环境变量 |
GetWithCmd |
配置文件 > 命令行 |
现有方法的优先级是配置文件优先,环境变量和命令行仅作为 fallback。这与 12-Factor App 的推荐相反,无法满足"通过环境变量/命令行覆盖配置文件"的常见需求。
此外,GetWithEnv / GetWithCmd 的命名容易造成误解,让用户误以为与 Spring Boot 类似——只是多了一个数据源,而没有意识到优先级是相反的。
建议方案
新增方法,采用标准优先级:
命令行参数 > 环境变量 > 配置文件 > 默认值
API 设计:
// 按标准优先级获取配置值
// 优先级:命令行参数 > 环境变量 > 配置文件 > 默认值
func (c *Config) GetEffective(ctx context.Context, pattern string, def ...interface{}) (*gvar.Var, error)
// Must 版本
func (c *Config) MustGetEffective(ctx context.Context, pattern string, def ...interface{}) *gvar.Var使用示例:
// 配置文件 config.yaml:
// server:
// port: 8080
// 启动命令: ./app --server.port=9090
// 或环境变量: SERVER_PORT=9090 ./app
port := cfg.MustGetEffective(ctx, "server.port", 8000)
// 优先使用命令行参数 9090
// 若无命令行参数,使用环境变量 SERVER_PORT
// 若无环境变量,使用配置文件 8080
// 若无配置文件,使用默认值 8000关于命名:
暂定命名为 GetEffective,表示"经过优先级合并后实际生效的值"。"Effective" 在配置领域是常用术语,Kubernetes 中也有类似用法,如 effectiveAnnotations、effectivePodSecurityPolicy 等表示最终生效的配置。
命名仅供参考,可根据讨论调整。
兼容性
- 保留现有
Get、GetWithEnv、GetWithCmd方法,不做任何改动 - 新方法推荐作为获取配置的首选方式
- 在文档中说明各方法的优先级差异,引导用户根据场景选择
相关参考
gqcn
Metadata
Metadata
Assignees
Labels
awesomeIt's awesome! We keep watching.It's awesome! We keep watching.discussWe need discuss to make decision.We need discuss to make decision.feature