golang轻量级零依赖可扩展配置管理插件库uConfig的使用
Golang轻量级零依赖可扩展配置管理插件库uConfig的使用
uConfig是一个轻量级、零依赖且可扩展的配置管理库。它通过插件机制提供配置管理功能,可以组合使用标志(flags)、环境变量、默认值、密钥提供程序等各种配置源。
基本使用示例
数据库配置示例
package database
// Config 保存数据库配置
type Config struct {
Address string `default:"localhost"`
Port string `default:"28015"`
Database string `default:"my-project"`
}
Redis配置示例
package redis
// Config 描述Redis客户端的需求
type Config struct {
Address string `default:"redis-master"`
Port string `default:"6379"`
Password string `secret:""`
DB int `default:"0"`
Expire time.Duration `default:"5s"`
}
主程序配置示例
package main
import (
"encoding/json"
"fmt"
"os"
"github.com/omeid/uconfig"
"$PROJECT/redis"
"$PROJECT/database"
)
// Config 是我们的应用程序配置
type Config struct {
// 支持切片类型
Hosts []string `default:"localhost,localhost.local" usage:"要绑定的IP或域名"`
Redis redis.Config
Database database.Config
}
func main() {
conf := &Config{}
files := uconfig.Files{
{"config.json", json.Unmarshal, true},
// 可以添加任意多个文件,它们会按给定顺序应用
}
_, err := uconfig.Classic(&conf, files)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// 使用conf配置
// 例如以JSON格式漂亮打印
configAsJson, err := json.MarshalIndent(conf, "", " ")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Print(string(configAsJson))
}
自定义名称
可以通过两种方式自定义字段名称:
- 使用
uconfig
标签 - 这会改变uConfig看到的字段名称,支持嵌套前缀 - 使用插件特定标签 - 这只会影响特定插件看到的字段名称
package database
// Config 保存数据库配置
type Database struct {
Address string `default:"localhost"`
Port string `default:"28015" uconfig:"Service.Port"`
Database string `default:"my-project" env:"DB_NAME" flag:"main-db-name"`
}
密钥插件
密钥插件允许从任何地方获取配置值。只需实现func(name string) (value string)
函数并将其传递给密钥插件。
import (
"github.com/omeid/uconfig"
"github.com/omeid/uconfig/plugins/secret"
)
// Creds 是使用密钥值的配置结构体示例
type Creds struct {
// 默认情况下,密钥插件会生成与env插件相同的名称(SCREAM_SNAKE_CASE)
// 在下面的Config结构中,它会变成CREDS_APIKEY
APIKey string `secret:""`
// 或者可以提供自己的名称,不受嵌套或字段名影响
APIToken string `secret:"API_TOKEN"`
}
type Config struct {
Redis Redis
Creds Creds
}
func main() {
conf := &Config{}
files := uconfig.Files{
{"config.json", json.Unmarshal, false}
}
// secret.New接受一个将密钥名映射到其值的函数
secretPlugin := secret.New(func(name string) (string, error) {
// 可以从任何地方获取密钥,如AWS secrets-manager、Hashicorp Vault等
value, ok := secretSource.Get(name)
if !ok {
return "", ErrSecretNotFound
}
return value, nil
})
// 然后可以像其他插件一样使用secretPlugin
_, err := uconfig.Classic(&conf, files, secretPlugin)
if err != nil {
t.Fatal(err)
}
}
测试
对于测试,可以使用Must
函数设置默认值:
package something
import (
"testing"
"github.com/omeid/uconfig"
"github.com/omeid/uconfig/defaults"
)
func TestSomething(t *testing.T) error {
conf := &YourConfigStruct{}
// 出错时会panic
uconfig.Must(conf, defaults.New())
// 使用你的配置
}
扩展uConfig
uConfig提供插件机制来添加新的配置源。有两种插件:
访问器(Visitors)
访问器获取配置结构的平面视图,适用于从平面结构加载配置的插件(如标志、环境变量、默认标签等)。
遍历器(Walkers)
遍历器用于获取整个配置结构并将其解组到配置结构中的插件。适用于从文件加载配置的插件。
通过实现这些插件接口,可以轻松扩展uConfig的功能。
更多关于golang轻量级零依赖可扩展配置管理插件库uConfig的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang轻量级零依赖可扩展配置管理插件库uConfig的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
uConfig - 轻量级零依赖的Go配置管理库
uConfig是一个轻量级、零外部依赖的Go语言配置管理库,它支持多种配置源和灵活的扩展方式。下面我将详细介绍uConfig的使用方法。
基本特性
- 零外部依赖
- 支持多种配置源:环境变量、命令行参数、JSON/YAML文件等
- 易于扩展自定义配置源
- 结构体标签配置
- 类型安全
安装
go get github.com/omeid/uconfig
基本使用
1. 定义配置结构
type Config struct {
Host string `default:"localhost"`
Port int `default:"8080"`
Debug bool
Timeout time.Duration `default:"30s"`
Database struct {
URL string `default:"postgres://localhost:5432"`
PoolSize int `default:"10"`
}
}
2. 初始化配置
func main() {
var conf Config
// 创建配置管理器
c, err := uconfig.New(&conf)
if err != nil {
log.Fatalf("Failed to initialize config: %v", err)
}
// 添加配置源
c.AddSource(uconfig.Default{}) // 默认值
c.AddSource(uconfig.FlagSource()) // 命令行参数
c.AddSource(uconfig.EnvSource()) // 环境变量
// 解析配置
if err := c.Parse(); err != nil {
log.Fatalf("Failed to parse config: %v", err)
}
fmt.Printf("Config: %+v\n", conf)
}
3. 运行程序
可以通过多种方式提供配置:
# 使用默认值
./myapp
# 通过命令行参数
./myapp --host=example.com --port=9090 --debug=true
# 通过环境变量
HOST=example.com PORT=9090 DEBUG=true ./myapp
高级功能
自定义配置源
uConfig允许你轻松添加自定义配置源:
type CustomSource struct {
data map[string]interface{}
}
func (c CustomSource) Parse() (map[string]interface{}, error) {
return c.data, nil
}
func main() {
var conf Config
c, err := uconfig.New(&conf)
if err != nil {
log.Fatal(err)
}
// 添加自定义配置源
c.AddSource(CustomSource{
data: map[string]interface{}{
"host": "custom.host",
"port": 1234,
},
})
if err := c.Parse(); err != nil {
log.Fatal(err)
}
fmt.Printf("Config: %+v\n", conf)
}
文件配置源
uConfig内置了文件配置源支持:
func main() {
var conf Config
c, err := uconfig.New(&conf)
if err != nil {
log.Fatal(err)
}
// 添加JSON文件配置源
c.AddSource(uconfig.FileSource("config.json"))
if err := c.Parse(); err != nil {
log.Fatal(err)
}
fmt.Printf("Config: %+v\n", conf)
}
配置验证
uConfig可以与验证库结合使用:
import "github.com/go-playground/validator/v10"
type Config struct {
Host string `validate:"required"`
Port int `validate:"min=1,max=65535"`
}
func main() {
var conf Config
c, err := uconfig.New(&conf)
if err != nil {
log.Fatal(err)
}
c.AddSource(uconfig.Default{})
c.AddSource(uconfig.FlagSource())
if err := c.Parse(); err != nil {
log.Fatal(err)
}
// 验证配置
validate := validator.New()
if err := validate.Struct(conf); err != nil {
log.Fatalf("Config validation failed: %v", err)
}
}
最佳实践
-
配置优先级:后添加的配置源优先级更高,通常顺序是:默认值 < 环境变量 < 命令行参数 < 文件配置
-
敏感信息:对于敏感配置如密码,建议使用环境变量或专门的secret管理工具
-
配置结构:合理组织配置结构,避免过于扁平或过于嵌套
-
默认值:为所有配置项提供合理的默认值
-
文档:为配置结构添加注释说明每个字段的用途和格式
uConfig是一个简单但功能强大的配置管理库,特别适合需要轻量级解决方案的项目。它的零依赖特性使得项目依赖关系保持简洁,而灵活的扩展机制又能满足各种复杂场景的需求。