golang统一读取多源配置数据的插件库go-cfg的使用
Golang统一读取多源配置数据的插件库go-cfg的使用
简介
go-cfg是一个用于从多种来源(如环境变量、命令行标志和配置文件)读取配置数据的Go库。该库提供了统一的接口来读取配置数据,使得管理和维护应用程序配置更加容易。
安装
使用以下命令安装库:
go get github.com/dsbasko/go-cfg
使用示例
基本用法
package main
import (
"github.com/dsbasko/go-cfg"
)
type Config struct {
Mode string `default:"prod" json:"mode" yaml:"mode" s-flag:"m" flag:"mode" env:"MODE" description:"mode of the application (dev|prod)"`
HTTP struct {
Host string `default:"localhost" json:"host" yaml:"host" s-flag:"h" flag:"http-host" env:"HTTP_HOST"`
Port int `default:"3000" json:"port" yaml:"port" s-flag:"p" flag:"http-port" env:"HTTP_PORT"`
ReadTimeout int `json:"read_timeout" yaml:"read-timeout" flag:"http-read-timeout" env:"HTTP_READ_TIMEOUT"`
WriteTimeout int `json:"write_timeout" yaml:"write-timeout" flag:"http-write-timeout" env:"HTTP_WRITE_TIMEOUT"`
} `json:"http" yaml:"http"`
}
func main() {
cfg := Config{}
gocfg.MustReadFile("configs/config.yaml", &cfg)
gocfg.MustReadEnv(&cfg)
gocfg.MustReadFlag(&cfg)
}
命令行标志
type config struct {
WithShort string `s-flag:"s" flag:"with-short" description:"With short flag"`
Flat string `flag:"flat" description:"Flat flag"`
Parent struct {
Nested string `flag:"nested" description:"Nested flag"`
}
}
func main() {
var cfg config
if err := gocfg.ReadFlag(&cfg); err != nil {
log.Panicf("failed to read flag: %v", err)
}
// 或者: gocfg.MustReadFlag(&cfg)
log.Printf("WithShort: %v\n", cfg.WithShort)
log.Printf("Flat: %v\n", cfg.Flat)
log.Printf("Nested: %v\n", cfg.Parent.Nested)
}
环境变量
type config struct {
Flat string `env:"FLAT"`
Parent struct {
Nested string `env:"NESTED"`
}
}
func main() {
var cfg config
if err := gocfg.ReadEnv(&cfg); err != nil {
log.Panicf("failed to read env: %v", err)
}
// 或者: gocfg.MustReadEnv(&cfg)
log.Printf("Flat: %v\n", cfg.Flat)
log.Printf("Nested: %v\n", cfg.Parent.Nested)
}
配置文件
type config struct {
Flat string `yaml:"flat"`
Parent struct {
Nested string `yaml:"nested"`
}
}
func main() {
var cfg config
if err := gocfg.ReadFile(path.Join("cmd", "config.yaml"), &cfg); err != nil {
log.Panicf("failed to read config.yaml file: %v", err)
}
// 或者: gocfg.MustReadFile(path.Join("cmd", "config.yaml"), &cfg)
log.Printf("Flat: %v\n", cfg.Flat)
log.Printf("Nested: %v\n", cfg.Parent.Nested)
}
对应的YAML配置文件内容:
flat: f1
foo:
nested: n1
结构体标签说明
命令行标志标签
default
: 默认值flag
: 标志名称s-flag
: 短标志名(1个字符)description
: 标志描述,在使用--help
命令时显示
环境变量标签
default
: 默认值env
: 环境变量名称
配置文件标签
default
: 默认值env
: 用于.env
格式文件yaml
: 用于.yaml
或.yml
格式文件toml
: 用于.toml
格式文件json
: 用于.json
格式文件
注意事项
该库使用了env、pflag、yaml、toml和godotenv的代码库来处理环境变量和标志。这是一个临时解决方案,未来可能会实现自己的版本。感谢这些库的作者所做的工作!
更多关于golang统一读取多源配置数据的插件库go-cfg的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang统一读取多源配置数据的插件库go-cfg的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
go-cfg: Golang统一读取多源配置数据的插件库
go-cfg 是一个用于统一读取多种配置源数据的Golang库,它提供了简洁的API来从不同来源(如文件、环境变量、命令行参数等)加载配置,并支持配置合并和优先级设置。
主要特性
- 支持多种配置源:JSON、YAML、TOML、环境变量、命令行参数等
- 配置合并功能,支持设置优先级
- 支持配置热更新
- 简单易用的API
- 支持自定义配置源
安装
go get github.com/go-cfg/cfg
基本使用示例
package main
import (
"fmt"
"log"
"github.com/go-cfg/cfg"
)
type Config struct {
Server struct {
Host string `json:"host" yaml:"host" env:"SERVER_HOST"`
Port int `json:"port" yaml:"port" env:"SERVER_PORT"`
} `json:"server" yaml:"server"`
Database struct {
URL string `json:"url" yaml:"url" env:"DB_URL"`
Username string `json:"username" yaml:"username" env:"DB_USER"`
Password string `json:"password" yaml:"password" env:"DB_PASS"`
} `json:"database" yaml:"database"`
}
func main() {
var config Config
// 创建配置加载器
loader := cfg.New(
// 从环境变量加载
cfg.WithEnv(),
// 从JSON文件加载
cfg.WithFile("config.json", cfg.JSON),
// 从YAML文件加载
cfg.WithFile("config.yaml", cfg.YAML),
)
// 加载配置
if err := loader.Load(&config); err != nil {
log.Fatalf("Failed to load config: %v", err)
}
// 使用配置
fmt.Printf("Server: %s:%d\n", config.Server.Host, config.Server.Port)
fmt.Printf("Database: %s@%s\n", config.Database.Username, config.Database.URL)
}
高级用法
1. 设置配置源优先级
loader := cfg.New(
// 低优先级 - 首先尝试从JSON文件加载
cfg.WithFile("config.json", cfg.JSON, cfg.Priority(10)),
// 高优先级 - 然后从环境变量加载,会覆盖JSON中的配置
cfg.WithEnv(cfg.Priority(20)),
// 最高优先级 - 最后从命令行参数加载,会覆盖所有其他配置
cfg.WithFlag(cfg.Priority(30)),
)
2. 配置热更新
// 创建支持热更新的加载器
loader := cfg.New(
cfg.WithFile("config.yaml", cfg.YAML, cfg.Watch(true)),
)
var config Config
if err := loader.Load(&config); err != nil {
log.Fatal(err)
}
// 监听配置变更
ch := loader.Watch()
go func() {
for {
select {
case <-ch:
// 配置已更新,重新加载
if err := loader.Load(&config); err != nil {
log.Printf("Failed to reload config: %v", err)
} else {
log.Println("Config reloaded successfully")
}
}
}
}()
3. 自定义配置源
// 实现cfg.Source接口
type MyCustomSource struct {
data map[string]interface{}
}
func (s *MyCustomSource) Load() (map[string]interface{}, error) {
return s.data, nil
}
func (s *MyCustomSource) Priority() int {
return 15
}
// 使用自定义配置源
customSource := &MyCustomSource{
data: map[string]interface{}{
"server": map[string]interface{}{
"host": "custom.host",
"port": 8080,
},
},
}
loader := cfg.New(
cfg.WithSource(customSource),
)
配置合并规则
go-cfg 按照以下规则合并配置:
- 按优先级从低到高依次加载配置
- 高优先级配置会覆盖低优先级配置中的相同字段
- 对于嵌套结构,会递归合并
- 数组类型会被完全替换而不是合并
最佳实践
- 定义清晰的结构体来表示配置
- 为配置字段添加适当的标签(json、yaml、env等)
- 合理设置配置源优先级
- 生产环境中建议使用环境变量或密钥管理服务存储敏感信息
- 开发环境可以使用配置文件方便修改
总结
go-cfg 是一个功能强大且灵活的配置管理库,它简化了从多种来源加载和合并配置的过程。通过统一的接口,开发者可以轻松管理应用程序的配置,而无需关心底层配置源的细节。无论是小型项目还是大型分布式系统,go-cfg 都能提供良好的配置管理解决方案。