golang轻量级强大配置管理插件库GoLobby/Config的使用

Golang轻量级强大配置管理插件库GoLobby/Config的使用

Go Reference CI CodeQL Go Report Card Coverage Status Mentioned in Awesome Go

简介

GoLobby Config是一个轻量级但功能强大的Go项目配置管理器。它利用Dot-env(.env)文件、OS环境变量以及配置文件(JSON、YAML和TOML)来满足您的所有需求。

要求

需要Go v1.16或更高版本。

安装

在项目根目录运行以下命令安装:

go get github.com/golobby/config/v3

快速开始

以下示例演示如何使用JSON配置文件:

// 配置结构体
type MyConfig struct {
    App struct {
        Name string
        Port int
    }
    Debug      bool
    Production bool
    Pi         float64
}

// 创建配置结构体实例
myConfig := MyConfig{}

// 创建从JSON文件提供配置数据的feeder
jsonFeeder := feeder.Json{Path: "config.json"}

// 创建Config实例并使用jsonFeeder填充myConfig
c := config.New()
c.AddFeeder(jsonFeeder)
c.AddStruct(&myConfig)
err := c.Feed()

// 或使用方法链:
// err := config.New().AddFeeder(jsonFeeder).AddStruct(&myConfig).Feed()

// 使用myConfig...

Feeders

Feeders提供配置数据。GoLobby Config包支持以下内置feeders:

  • Json: 使用JSON文件
  • Yaml: 使用YAML文件
  • Toml: 使用TOML文件
  • DotEnv: 使用dot env(.env)文件
  • Env: 使用OS环境变量

您也可以通过实现Feeder接口创建自定义feeders或使用第三方feeders。

Json Feeder

Json feeder使用Go内置的json包加载JSON文件:

jsonFeeder := feeder.Json{Path: "sample1.json"}
c := config.New().AddFeeder(jsonFeeder)

Yaml Feeder

Yaml feeder使用YAML包(v3)加载YAML文件:

yamlFeeder := feeder.Yaml{Path: "sample1.yaml"}
c := config.New().AddFeeder(yamlFeeder)

Toml Feeder

Toml feeder使用BurntSushi TOML包加载TOML文件:

tomlFeeder := feeder.Toml{Path: "sample1.toml"}
c := config.New().AddFeeder(tomlFeeder)

DotEnv Feeder

DotEnv feeder使用GoLobby DotEnv包加载.env文件:

type MyConfig struct {
    App struct {
        Name string `env:"APP_NAME"`
        Port int    `env:"APP_PORT"`
    }
    Debug      bool    `env:"DEBUG"`
    Production bool    `env:"PRODUCTION"`
    Pi         float64 `env:"PI"`
    IDs        []int   `env:"IDS"`
}

myConfig := MyConfig{}
dotEnvFeeder := feeder.DotEnv{Path: ".env"}
err := config.New().AddFeeder(dotEnvFeeder).AddStruct(&myConfig).Feed()

必须为每个字段添加env标签以确定相关的dot env变量。如果相关文件中没有字段的值,它将忽略结构体字段。

Env Feeder

Env feeder基于GoLobby Env包构建:

type MyConfig struct {
    App struct {
        Name string `env:"APP_NAME"`
        Port int    `env:"APP_PORT"`
    }
    Debug      bool     `env:"DEBUG"`
    Production bool     `env:"PRODUCTION"`
    Pi         float64  `env:"PI"`
    IPs        []string `env:"IPS"`
    IDs        []int16  `env:"IDS"`
}

_ = os.Setenv("APP_NAME", "Shop")
_ = os.Setenv("APP_PORT", "8585")
_ = os.Setenv("DEBUG", "true")
_ = os.Setenv("PRODUCTION", "false")
_ = os.Setenv("PI", "3.14")
_ = os.Setenv("IPS", "192.168.0.1", "192.168.0.2")
_ = os.Setenv("IDS", "10, 11, 12, 13")

myConfig := MyConfig{}
envFeeder := feeder.DotEnv{}
err := config.New().AddFeeder(envFeeder).AddStruct(&myConfig).Feed()

必须为每个字段添加env标签以确定相关的OS环境变量名。如果OS环境变量中没有字段的值,它将忽略结构体字段。

多个Feeders

GoLobby Config包的关键特性之一是使用多个feeders进行配置。后添加的feeders会覆盖先添加的。

以下示例演示如何使用JSON文件作为主配置feeder,并用dot env和os变量覆盖配置:

type MyConfig struct {
    App struct {
        Name string `env:"APP_NAME"`
        Port int    `env:"APP_PORT"`
    }
    Debug      bool    `env:"DEBUG"`
    Production bool    `env:"PRODUCTION"`
    Pi         float64 `env:"PI"`
    IDs        []int32 `env:"IDS"`
}

_ = os.Setenv("PRODUCTION", "true")
_ = os.Setenv("APP_PORT", "6969")
_ = os.Setenv("IDs", "6, 9")

myConfig := MyConfig{}

feeder1 := feeder.Json{Path: "sample1.json"}
feeder2 := feeder.DotEnv{Path: ".env.sample2"}
feeder3 := feeder.Env{}

err := config.New().AddFeeder(feeder1, feeder2, feeder3).AddStruct(&myConfig).Feed()

fmt.Println(c.App.Name)   // Blog  [from DotEnv]
fmt.Println(c.App.Port)   // 6969  [from Env]
fmt.Println(c.Debug)      // false [from DotEnv]
fmt.Println(c.Production) // true  [from Env]
fmt.Println(c.Pi)         // 3.14  [from Json]
fmt.Println(c.IDs)        // 6, 9  [from Env]

Setup方法

Setup()方法在feeding后自动运行。您可以使用此方法进行后处理逻辑:

type Region int

const (
    Asia Region = iota
    Europe
    America
    Else
)

type Config struct {
    RegionId int `env:"REGION"`
    Region   Region
}

func (c *Config) Setup() error {
    if fc.RegionId == 0 {
        fc.Region = Asia
    } else if fc.RegionId == 1 {
        fc.Region = Europe
    } else if fc.RegionId == 2 {
        fc.Region = America
    } else if fc.RegionId == 3 {
        fc.Region = Else
    } else {
        return errors.New("invalid region")
    }
    return nil
}

_ = os.Setenv("REGION", "2")

myConfig := Config{}
f := feeder.Env{}

err := config.New().AddFeeder(f).AddStruct(&myConfig).Feed()

fmt.Println(c.Region) // America (2)

重新Feed

您可以在需要时重新填充结构体。只需再次调用Feed()方法:

c := config.New().AddFeeder(feeder).AddStruct(&myConfig)
err := c.Feed()

// 是时候重新feed了吗?
err = c.Feed()

// 使用更新后的myConfig数据!

监听器

GoLobby Config的特性之一是能够在无需重新部署的情况下更新配置结构体。它利用OS信号来处理此需求。Config实例监听"SIGHUP"操作系统信号并刷新结构体(调用Feed()方法)。

要为Config实例启用监听器,您应该调用SetupListener()方法。它获取一个回退函数,并在Feed()方法失败并返回错误时调用它。

c := config.New().AddFeeder(feeder).AddStruct(&myConfig)
c.SetupListener(func(err error) {
    fmt.Println(err)
})

err := c.Feed()

您可以使用以下shell命令向正在运行的应用程序发送SIGHUP信号:

KILL -SIGHUP [YOUR-APP-PROCESS-ID]

您可以使用ps命令获取应用程序进程ID。

许可证

GoLobby Config根据MIT许可证发布。


更多关于golang轻量级强大配置管理插件库GoLobby/Config的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻量级强大配置管理插件库GoLobby/Config的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


GoLobby/Config 轻量级配置管理库使用指南

GoLobby/Config 是一个轻量级但功能强大的 Go 语言配置管理库,支持多种配置格式,包括 JSON、YAML、TOML 和 ENV 等。下面我将详细介绍它的使用方法和示例代码。

安装

首先安装 GoLobby/Config:

go get github.com/golobby/config/v3

基本使用

1. 加载配置文件

package main

import (
	"fmt"
	"github.com/golobby/config/v3"
	"github.com/golobby/config/v3/pkg/feeder"
)

type Config struct {
	App struct {
		Name    string `json:"name" yaml:"name"`
		Version string `json:"version" yaml:"version"`
	} `json:"app" yaml:"app"`
	Database struct {
		Host     string `json:"host" yaml:"host"`
		Port     int    `json:"port" yaml:"port"`
		Username string `json:"username" yaml:"username"`
		Password string `json:"password" yaml:"password"`
	} `json:"database" yaml:"database"`
}

func main() {
	// 创建配置实例
	c := config.New()

	// 添加 JSON 配置源
	err := c.AddFeeder(feeder.Json{Path: "config.json"}).AddStruct(&Config{}).Feed()
	if err != nil {
		panic(err)
	}

	// 获取配置
	var cfg Config
	err = c.Bind(&cfg)
	if err != nil {
		panic(err)
	}

	fmt.Printf("App Name: %s\n", cfg.App.Name)
	fmt.Printf("Database Host: %s\n", cfg.Database.Host)
}

2. 多格式支持

GoLobby/Config 支持多种配置格式:

// 加载 YAML 配置
err := c.AddFeeder(feeder.Yaml{Path: "config.yaml"}).AddStruct(&Config{}).Feed()

// 加载 TOML 配置
err := c.AddFeeder(feeder.Toml{Path: "config.toml"}).AddStruct(&Config{}).Feed()

// 加载环境变量
err := c.AddFeeder(feeder.Env{Path: ".env"}).AddStruct(&Config{}).Feed()

3. 多配置源合并

可以合并多个配置源,后面的配置会覆盖前面的:

err := c.AddFeeder(
	feeder.Json{Path: "config.default.json"},
	feeder.Json{Path: "config.production.json"},
).AddStruct(&Config{}).Feed()

4. 直接获取配置值

// 获取嵌套配置值
appName, err := c.Get("app.name")
if err != nil {
	panic(err)
}
fmt.Println("App Name:", appName)

// 获取数据库端口
dbPort, err := c.GetInt("database.port")
if err != nil {
	panic(err)
}
fmt.Println("DB Port:", dbPort)

高级功能

1. 环境变量覆盖

err := c.AddFeeder(
	feeder.Json{Path: "config.json"},
	feeder.Env{Prefix: "MYAPP_"}, // 只加载以 MYAPP_ 开头的环境变量
).AddStruct(&Config{}).Feed()

2. 监听配置变化

// 创建带监听功能的配置
c := config.New()
c.AddFeeder(feeder.Json{Path: "config.json", Watch: true}) // 启用监听
c.AddStruct(&Config{})

// 启动配置监听
go func() {
	for {
		<-c.Watch()
		fmt.Println("Configuration changed!")
		var newCfg Config
		_ = c.Bind(&newCfg)
		fmt.Printf("New App Name: %s\n", newCfg.App.Name)
	}
}()

// 主程序
err := c.Feed()
if err != nil {
	panic(err)
}

3. 自定义配置源

你可以实现 Feeder 接口创建自定义配置源:

type MyFeeder struct {
	Content string
}

func (f MyFeeder) Feed() (map[string]interface{}, error) {
	// 解析 f.Content 并返回配置map
	// 示例简化,实际需要实现解析逻辑
	return map[string]interface{}{
		"app": map[string]interface{}{
			"name":    "MyApp",
			"version": "1.0",
		},
	}, nil
}

// 使用自定义配置源
err := c.AddFeeder(MyFeeder{Content: "..."}).AddStruct(&Config{}).Feed()

最佳实践

  1. 配置结构体分离:将不同模块的配置分离到不同结构体
  2. 默认配置:提供默认配置文件,允许环境特定配置覆盖
  3. 环境区分:使用不同配置文件如 config.dev.json, config.prod.json
  4. 敏感信息:敏感数据如密码应从环境变量或密钥管理服务加载
// 示例:根据环境加载不同配置
func loadConfig(env string) (*Config, error) {
	c := config.New()
	
	// 加载默认配置
	err := c.AddFeeder(feeder.Json{Path: "config.default.json"}).AddStruct(&Config{}).Feed()
	if err != nil {
		return nil, err
	}
	
	// 加载环境特定配置
	if env != "" {
		envFile := fmt.Sprintf("config.%s.json", env)
		err = c.AddFeeder(feeder.Json{Path: envFile}).AddStruct(&Config{}).Feed()
		if err != nil {
			return nil, err
		}
	}
	
	// 加载环境变量覆盖
	err = c.AddFeeder(feeder.Env{Prefix: "APP_"}).AddStruct(&Config{}).Feed()
	if err != nil {
		return nil, err
	}
	
	var cfg Config
	err = c.Bind(&cfg)
	return &cfg, err
}

GoLobby/Config 以其轻量级和灵活性成为 Go 项目中配置管理的优秀选择,特别适合需要支持多种配置格式和环境覆盖的场景。

回到顶部