golang零配置多源优先级管理插件库zerocfg的使用
Golang零配置多源优先级管理插件库zerocfg的使用
zerocfg是一个受Go flag包启发的零配置管理库,支持多配置源和优先级管理。它提供了简单灵活的API,支持YAML配置,并且禁止样板代码。
特性
- 🛠️ 受flag包启发的简单灵活API
- 🍳 设计上禁止样板代码
- 🚦 早期检测错误配置键
- ✨ 支持多配置源和基于优先级的值解析
- 🕵️♂️ 支持隐藏敏感配置
- 🧩 支持自定义选项类型和提供者
安装
go get -u github.com/chaindead/zerocfg
快速开始
package main
import (
"fmt"
zfg "github.com/chaindead/zerocfg"
"github.com/chaindead/zerocfg/env"
"github.com/chaindead/zerocfg/yaml"
)
var (
// 配置变量
path = zfg.Str("config.path", "", "path to yaml conf file", zfg.Alias("c"))
ip = zfg.IP("db.ip", "127.0.0.1", "database location")
port = zfg.Uint("db.port", 5678, "database port")
username = zfg.Str("db.user", "guest", "user of database")
password = zfg.Str("db.password", "qwerty", "password for user", zfg.Secret())
)
func main() {
// 使用多源初始化配置
err := zfg.Parse(
env.New(),
yaml.New(path),
)
if err != nil {
panic(err)
}
fmt.Printf("Connect to %s:%d creds=%s:%s\n", *ip, *port, *username, *password)
// 输出: Connect to 127.0.0.1:5678 creds=guest:qwerty
fmt.Println(zfg.Show())
// 命令: go run ./... -c test.yaml
// 输出:
// config.path = test.yaml (path to yaml conf file)
// db.ip = 127.0.0.1 (database location)
// db.password = <secret> (password for user)
// db.port = 5678 (database port)
// db.user = guest (user of database)
}
使用说明
选项命名
- 使用点(.)作为分层选项的分隔符
- 选项子名称推荐使用camelCase、下划线(_)和短横线(-)风格
zfg.Str("groupOptions.thisOption", "", "camelCase usage")
zfg.Str("group_options.this_option", "", "underscore usage")
zfg.Str("group-options.this-option", "", "dash usage")
限制
- 选项在导入时注册,不支持运行时动态注册
- 不允许键重复
- 不允许同时使用键和子键(如
map
和map.value
)
未知值处理
如果zfg.Parse
遇到未知值(未注册为选项的变量),它会返回错误。但可以选择忽略未知值:
err := zfg.Parse(
env.New(),
yaml.New(path),
)
if u, ok := zfg.IsUnknown(err); !ok {
panic(err)
} else {
// u是<source_name>到未知键切片的映射
fmt.Println(u)
}
env
源不会触发未知选项以避免误报
复杂类型作为字符串
- 基本值通过
fmt.Sprint("%v")
转换 - 如果类型有
String()
方法,则使用它(如time.Duration
) - 否则使用JSON表示复杂类型(如切片、映射)
var (
_ = zfg.Dur("timeout", 5*time.Second, "duration via fmt.Stringer interface")
_ = zfg.Floats64("floats", nil, "list via json")
)
func main() {
_ = zfg.Parse()
fmt.Printf(zfg.Show())
// 命令: go run ./... --timeout 10s --floats '[1.1, 2.2, 3.3]'
// 输出:
// floats = [1.1,2.2,3.3] (list via json)
// timeout = 10s (duration via fmt.Stringer interface)
}
配置源
配置系统遵循严格的优先级层次结构:
- 命令行参数(始终最高优先级,默认启用)
- 按添加顺序的可选提供者(先添加=更高优先级)
- 默认值(最低优先级)
命令行参数
- 默认启用,始终具有最高优先级
- 可以为选项定义别名方便CLI使用
- 值作为空格分隔的参数传递(不允许使用=)
- 支持单横线(-)和双横线(–)前缀
path := zfg.Str("config.path", "", "path to yaml conf file", zfg.Alias("c"))
运行方式:
go run ./... -c test.yaml
# 或
go run ./... --config.path test.yaml
环境变量
环境变量会自动从配置键格式转换:
配置键 | 环境变量 | 说明 |
---|---|---|
db.user | DB_USER | 基本转换 |
app.api.key | APP_API_KEY | 多级路径 |
camelCase.value | CAMELCASE_VALUE | 驼峰式处理 |
api-key.secret | APIKEY_SECRET | 移除短横线 |
under_score.value | UNDERSCORE_VALUE | 移除下划线 |
转换规则:
- 移除特殊字符(保留字母、数字和点)
- 将点替换为下划线
- 转换为大写
示例:
import (
"fmt"
zfg "github.com/chaindead/zerocfg"
"github.com/chaindead/zerocfg/env"
)
var dbUser = zfg.Str("db.user", "", "database's username")
func main() {
_ = zfg.Parse(
env.New(),
)
fmt.Printf("DB user: %s", *dbUser)
}
运行方式:
DB_USER=admin go run main.go
# 输出: DB user: admin
YAML源
- 选项使用点路径映射到YAML键,支持分层配置
- 支持所有命名风格并按原样映射到YAML键
示例YAML文件:
group:
option: "foo"
numbers:
- 1
- 2
- 3
limits:
max: 10
min: 1
示例Go配置:
zfg.Str("group.option", "", "hierarchical usage")
zfg.Ints("numbers", nil, "slice of server configs")
zfg.Map("limits", nil, "map of limits")
高级用法
自定义选项
可以通过实现Value
接口并通过Any
函数注册来定义自己的选项类型。Set
和String
方法应该兼容。
// 自定义类型
type MyType struct{ V string }
func newValue(val MyType, p *MyType) zfg.Value {
*p = val
return p
}
func (m *MyType) Set(s string) error { m.V = s; return nil }
func (m *MyType) Type() string { return "custom" }
func (m *MyType) String() string { return m.V }
func Custom(name string, defVal MyType, desc string, opts ...zfg.OptNode) *MyType {
return zfg.Any(name, defVal, desc, newValue, opts...)
}
// 注册自定义选项
var myOpt = Custom("custom.opt", MyType{"default"}, "custom option")
自定义提供者
可以通过实现Provider
接口添加自己的配置源。
type MyProvider struct{}
func (p *MyProvider) Type() string { return "my" }
func (p *MyProvider) Provide(awaited map[string]bool, conv func(any) string) (map[string]string, map[string]string, error) {
found := map[string]string{}
unknown := map[string]string{}
// ... 根据awaited填充found/unknown ...
return found, unknown, nil
}
// 使用
zfg.Parse(&MyProvider{})
更多关于golang零配置多源优先级管理插件库zerocfg的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang零配置多源优先级管理插件库zerocfg的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
zerocfg - Golang零配置多源优先级管理插件库
zerocfg 是一个轻量级的 Golang 配置管理库,支持多配置源自动合并与优先级管理,无需繁琐的初始化配置即可使用。
核心特性
- 零配置开箱即用
- 多配置源自动合并(支持文件、环境变量、命令行参数等)
- 智能优先级管理
- 类型安全的值获取
- 支持动态监听配置变化
安装
go get github.com/zerocfg/zerocfg
基础用法
package main
import (
"fmt"
"github.com/zerocfg/zerocfg"
)
func main() {
// 零配置初始化
cfg := zerocfg.New()
// 获取配置值(自动从环境变量、命令行参数等来源获取)
port := cfg.GetInt("server.port", 8080) // 默认值8080
fmt.Printf("Server will run on port: %d\n", port)
// 获取字符串配置
env := cfg.GetString("app.env", "development")
fmt.Printf("Current environment: %s\n", env)
}
多源优先级示例
zerocfg 按照以下优先级顺序加载配置(从高到低):
- 命令行参数
- 环境变量
- 配置文件(如 config.yaml)
- 默认值
package main
import (
"fmt"
"github.com/zerocfg/zerocfg"
)
func main() {
cfg := zerocfg.New()
// 假设有以下配置来源:
// 1. 命令行: --db.host=127.0.0.1
// 2. 环境变量: DB_HOST=localhost
// 3. config.yaml: db.host: db.example.com
host := cfg.GetString("db.host", "default.host")
// 由于命令行优先级最高,将返回 "127.0.0.1"
fmt.Println("Database host:", host)
}
高级用法
添加自定义配置源
package main
import (
"fmt"
"github.com/zerocfg/zerocfg"
"github.com/zerocfg/source/memory"
)
func main() {
cfg := zerocfg.New()
// 添加内存配置源
memSource := memory.NewSource(map[string]interface{}{
"app.name": "MyApp",
"app.version": "1.0.0",
})
cfg.AddSource(memSource)
fmt.Println("App name:", cfg.GetString("app.name", ""))
fmt.Println("App version:", cfg.GetString("app.version", ""))
}
监听配置变化
package main
import (
"fmt"
"github.com/zerocfg/zerocfg"
"time"
)
func main() {
cfg := zerocfg.New()
// 监听配置变化
cfg.Watch("server.port", func(key string, value interface{}) {
fmt.Printf("Config changed: %s = %v\n", key, value)
})
// 模拟配置变化(实际中可能是文件修改或远程配置更新)
go func() {
time.Sleep(2 * time.Second)
cfg.Set("server.port", 9090)
}()
// 保持程序运行
select {}
}
使用结构体绑定
package main
import (
"fmt"
"github.com/zerocfg/zerocfg"
)
type ServerConfig struct {
Port int `cfg:"server.port"`
Host string `cfg:"server.host"`
}
func main() {
cfg := zerocfg.New()
var serverCfg ServerConfig
err := cfg.Unmarshal(&serverCfg)
if err != nil {
panic(err)
}
fmt.Printf("Server config: %+v\n", serverCfg)
}
最佳实践
- 为关键配置设置合理的默认值
- 使用命名空间(如 server.port)避免键冲突
- 生产环境优先使用环境变量或配置文件
- 开发环境可以使用命令行参数快速覆盖
性能考虑
zerocfg 在首次访问配置时会进行初始化加载,后续访问直接从缓存读取,性能开销极小。对于高频访问的配置项,建议在程序启动时获取并保存到局部变量中。
总结
zerocfg 提供了简单而强大的配置管理能力,特别适合需要灵活配置来源的微服务应用。其零配置设计让开发者可以快速集成,而多源优先级管理则确保了配置的灵活性和一致性。
更多高级用法和插件支持,请参考官方文档:https://github.com/zerocfg/zerocfg