config

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 13, 2026 License: MIT Imports: 12 Imported by: 0

README

config - Genesis 配置管理组件

Go Reference

基于 Viper 的多源配置加载组件。

特性

  • 多源配置:YAML/JSON 文件、环境变量、.env 文件
  • 配置优先级:环境变量 > .env > 环境特定配置 > 基础配置
  • 热更新:文件变化自动重载(支持基础配置和环境特定配置)
  • 多环境:支持 config.{env}.yaml

快速开始

loader, _ := config.New(&config.Config{
    Name:     "config",
    Paths:    []string{"./config"},
    FileType: "yaml",
})

err := loader.Load(ctx)
var cfg AppConfig
loader.Unmarshal(&cfg)

配置优先级

从高到低:

  1. 环境变量 (GENESIS_MYSQL_HOST)
  2. .env 文件
  3. 环境特定配置 (config.prod.yaml 合并到 config.yaml)
  4. 基础配置 (config.yaml)

注意.env 文件会覆盖同名环境变量(godotenv 默认行为),但 Viper 的 AutomaticEnv 会在 Get() 时优先读取运行时环境变量,因此最终效果仍是"运行时环境变量优先"。

API

type Config struct {
    Name      string   // 配置文件名(不含扩展名)
    Paths     []string // 搜索路径
    FileType  string   // yaml|json
    EnvPrefix string   // 环境变量前缀,默认 GENESIS
}

type Loader interface {
    Load(ctx) error
    Get(key) any
    Unmarshal(v) error
    UnmarshalKey(key, v) error
    Watch(ctx, key) (<-chan Event, error)
    Validate() error
}

type Event struct {
    Key       string
    Value     any
    OldValue  any
    Source    string  // "file" | "env"
    Timestamp time.Time
}

var (
    ErrNotFound         = xerrors.New("config file not found")
    ErrValidationFailed = xerrors.New("configuration validation failed")
)

func New(cfg *Config) (Loader, error)

热更新 (Watch)

监听配置变化,当文件修改时自动通知:

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

ch, _ := loader.Watch(ctx, "mysql.host")
for event := range ch {
    fmt.Printf("配置变化: %s = %v\n", event.Key, event.Value)
}

实现细节:

  • 无论调用多少次 Watch,内部只启动一个文件监听 goroutine
  • 返回的 channel 缓冲区大小为 10,若消费者处理过慢可能丢失事件
  • 监听基础配置文件和环境特定配置文件(如 config.yamlconfig.dev.yaml
  • .env 文件变更不会触发通知
  • 热更新时若配置文件读取失败,不会推送变更事件(静默忽略以避免中断服务)

环境特定配置

config/
├── config.yaml          # 基础配置
├── config.dev.yaml      # 开发环境(合并)
└── config.prod.yaml     # 生产环境(合并)

通过 GENESIS_ENV 环境变量指定环境。

环境变量映射

YAML 键 环境变量
mysql.host GENESIS_MYSQL_HOST
redis.addr GENESIS_REDIS_ADDR
app.debug GENESIS_APP_DEBUG

规则:{PREFIX}_{SECTION}_{KEY}(全大写,. 替换为 _

错误处理

loader, err := config.New(&config.Config{...})
if errors.Is(err, config.ErrNotFound) {
    // 配置文件未找到
}

示例配置

# config.yaml
app:
    name: "Genesis 应用"
    debug: false

mysql:
    host: "localhost"
    port: 3306

redis:
    addr: "localhost:6379"

Documentation

Overview

Package config 为 Genesis 提供统一的配置加载与变更通知能力,基于 Viper 实现。

特性:

  • 多源配置:YAML/JSON 文件、环境变量、.env 文件
  • 优先级语义(从高到低):进程环境变量 > .env 文件 > 环境配置 > 基础配置
  • 环境配置合并:支持 config.{env}.yaml 合并到基础配置
  • 文件变更通知:监听配置文件变化并向订阅者推送变更事件(带防抖)

注意事项:

  • .env 文件会覆盖同名环境变量(godotenv.Load 默认行为),若需"只补齐缺失项"语义, 请在启动前自行设置环境变量,Viper 的 AutomaticEnv 会确保运行时环境变量优先
  • 热更新时若配置文件读取失败,会静默忽略错误以避免中断服务,但不会推送变更事件

基本使用:

loader, err := config.New(&config.Config{
	Name:      "config",
	Paths:     []string{"./config"},
	FileType:  "yaml",
	EnvPrefix: "GENESIS",
})
if err != nil {
	panic(err)
}

if err := loader.Load(context.Background()); err != nil {
	panic(err)
}

var cfg AppConfig
if err := loader.Unmarshal(&cfg); err != nil {
	panic(err)
}

监听特定 Key 的变化:

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

ch, _ := loader.Watch(ctx, "app.debug")
for event := range ch {
	_ = event
}

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound 配置文件未找到
	ErrNotFound = xerrors.New("config file not found")

	// ErrValidationFailed 配置验证失败
	ErrValidationFailed = xerrors.New("configuration validation failed")
)

Functions

This section is empty.

Types

type Config

type Config struct {
	Name      string   // 配置文件名称(不含扩展名)
	Paths     []string // 配置文件搜索路径,默认 ["./", "./config"]
	FileType  string   // 配置文件类型 (yaml, json, etc.)
	EnvPrefix string   // 环境变量前缀,默认 "GENESIS"
}

Config 配置结构

type Event

type Event struct {
	Key       string // 配置 key
	Value     any    // 新值
	OldValue  any    // 旧值
	Source    string // "file" | "env" | "remote"
	Timestamp time.Time
}

Event 配置变更事件

type Loader

type Loader interface {
	// Load 加载配置并初始化内部状态
	Load(ctx context.Context) error

	// Get 获取原始配置值
	Get(key string) any

	// Unmarshal 将整个配置反序列化到结构体
	Unmarshal(v any) error

	// UnmarshalKey 将指定 Key 的配置反序列化到结构体
	UnmarshalKey(key string, v any) error

	// Watch 监听配置变化,通过 context 取消监听。
	//
	// 实现细节:
	//   - 无论调用多少次 Watch,内部只启动一个文件监听 goroutine(sync.Once 保证)
	//   - 返回的 channel 缓冲区大小为 10,若消费者处理过慢可能丢失事件(非阻塞发送)
	//   - 监听基础配置文件和环境特定配置文件(如 config.yaml 和 config.dev.yaml)
	//   - .env 文件变更不会触发通知
	//   - 热更新时若配置文件读取失败,不会推送变更事件,也不会返回错误
	Watch(ctx context.Context, key string) (<-chan Event, error)

	// Validate 验证当前配置的有效性
	Validate() error
}

Loader 定义配置加载器的核心行为 职责:加载、解析和监听配置变化

func New

func New(cfg *Config) (Loader, error)

New 创建配置加载器。

如果 cfg 为 nil,使用默认配置。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL