golang支持静态动态配置及Consul集成的配置管理插件harvester的使用

Golang支持静态动态配置及Consul集成的配置管理插件Harvester的使用

Harvester是一个配置管理库,可以帮助设置和监控配置值,以便动态重新配置您的应用程序。

配置来源

配置可以从以下来源获取:

  • 种子值:硬编码到配置结构中的值
  • 环境变量:从环境变量中获取
  • 命令行标志:从-flag=value形式的CLI标志中获取
  • 本地文件:从本地存储的文本文件中获取(不支持二进制文件)
  • Consul:用于获取初始值并监控变化

配置结构示例

type Config struct {
    IndexName      sync.String          `seed:"customers-v1"`
    CacheRetention sync.Int64           `seed:"86400" env:"ENV_CACHE_RETENTION_SECONDS"`
    LogLevel       sync.String          `seed:"DEBUG" flag:"loglevel"`
    Signature      sync.String          `file:"signature.txt"`
    Sandbox        sync.Bool            `seed:"true" env:"ENV_SANDBOX" consul:"/config/sandbox-mode"`
    AccessToken    sync.Secret          `seed:"defaultaccesstoken" env:"ENV_ACCESS_TOKEN" consul:"/config/access-token"`
    WorkDuration   sync.TimeDuration    `seed:"1s" env:"ENV_WORK_DURATION" consul:"/config/work-duration"`
    OpeningBalance sync.Float64         `seed:"0.0" env:"ENV_OPENING_BALANCE" redis:"opening-balance"`
}

支持的类型

Harvester支持以下并发安全类型:

  • sync.String:并发字符串操作
  • sync.Int64:并发int64操作
  • sync.Float64:并发float64操作
  • sync.Bool:并发bool操作
  • sync.Secret:并发secret操作(仅限字符串,日志中显示为***
  • sync.TimeDuration:并发time.duration操作
  • sync.Regexp:并发*regexp.Regexp操作
  • sync.StringMap:并发map[string]string操作
  • sync.StringSlice:并发[]string操作

构建Harvester实例

h, err := harvester.New(&cfg, chNotify,
    harvester.WithConsulSeed(consulAddress, consulDC, consulToken, 0),
    harvester.WithConsulMonitor(consulAddress, consulDC, consulToken, 0),
    harvester.WithRedisSeed(redisClient),
    harvester.WithRedisMonitor(redisClient, 200*time.Millisecond),
)

完整示例Demo

下面是一个完整的Harvester使用示例,包含Consul集成:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/beatlabs/harvester"
	"github.com/beatlabs/harvester/sync"
)

// Config 定义应用程序配置结构
type Config struct {
	IndexName    sync.String   `seed:"customers-v1" env:"ENV_INDEX_NAME" consul:"/config/index-name"`
	CacheEnabled sync.Bool     `seed:"true" env:"ENV_CACHE_ENABLED" consul:"/config/cache-enabled"`
	RefreshRate  sync.Int64    `seed:"30" env:"ENV_REFRESH_RATE" consul:"/config/refresh-rate"`
	AccessToken  sync.Secret   `seed:"default-token" env:"ENV_ACCESS_TOKEN" consul:"/config/access-token"`
	Timeout      sync.Duration `seed:"5s" env:"ENV_TIMEOUT" consul:"/config/timeout"`
}

func main() {
	// 初始化配置
	cfg := Config{}

	// Consul配置
	consulAddr := "localhost:8500"
	consulDC := "dc1"
	consulToken := ""

	// 创建通知通道
	chNotify := make(chan struct{})

	// 创建Harvester实例,带Consul种子和监控
	h, err := harvester.New(&cfg, chNotify,
		harvester.WithConsulSeed(consulAddr, consulDC, consulToken, 0),
		harvester.WithConsulMonitor(consulAddr, consulDC, consulToken, 0),
	)
	if err != nil {
		log.Fatalf("failed to create harvester: %v", err)
	}

	// 初始化配置
	if err = h.Harvest(context.Background()); err != nil {
		log.Fatalf("failed to harvest configuration: %v", err)
	}

	// 打印初始配置
	printConfig(&cfg)

	// 监控配置变化
	go func() {
		for {
			select {
			case <-chNotify:
				fmt.Println("\nConfiguration changed!")
				printConfig(&cfg)
			}
		}
	}()

	// 保持程序运行
	for {
		time.Sleep(1 * time.Minute)
	}
}

// printConfig 打印当前配置
func printConfig(cfg *Config) {
	fmt.Println("\nCurrent configuration:")
	fmt.Printf("IndexName: %s\n", cfg.IndexName.Get())
	fmt.Printf("CacheEnabled: %t\n", cfg.CacheEnabled.Get())
	fmt.Printf("RefreshRate: %d\n", cfg.RefreshRate.Get())
	fmt.Printf("AccessToken: %s\n", "***") // 敏感信息不直接显示
	fmt.Printf("Timeout: %v\n", cfg.Timeout.Get())
}

使用说明

  1. 种子阶段

    • 应用seed标签值(如果存在)
    • 应用环境变量值(如果存在)
    • 应用文件内容(如果存在)
    • 应用Consul返回值(如果存在且配置了Consul种子)
    • 应用CLI标志值(如果存在)
  2. 监控阶段(仅Consul):

    • 监控键并在标签键匹配时应用更改
    • 监控键前缀并在标签键匹配时应用更改(仅Consul)

注意事项

  • Consul支持版本控制(ModifyIndex),允许我们仅在版本高于当前版本时更改值
  • 对于敏感配置(密码、令牌等),使用Secret类型的sync变量,日志中将显示为***
  • 确保所有字段在种子阶段结束后都已正确初始化

更多关于golang支持静态动态配置及Consul集成的配置管理插件harvester的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang支持静态动态配置及Consul集成的配置管理插件harvester的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Harvester: Golang 配置管理插件详解

Harvester 是一个强大的 Go 语言配置管理库,支持静态和动态配置,并能与 Consul 集成实现配置中心化管理。下面我将详细介绍 Harvester 的使用方法。

1. Harvester 核心特性

  • 支持 JSON、YAML、TOML 等多种配置文件格式
  • 支持环境变量覆盖配置
  • 支持 Consul 作为配置中心
  • 支持动态配置重载
  • 提供监控配置变更的能力

2. 基本安装

go get github.com/beatlabs/harvester

3. 静态配置使用示例

3.1 定义配置结构

type Config struct {
    Server struct {
        Host string `seed:"localhost" env:"SERVER_HOST" json:"host"`
        Port int    `seed:"8080" env:"SERVER_PORT" json:"port"`
    } `json:"server"`
    LogLevel string `seed:"info" env:"LOG_LEVEL" json:"log_level"`
}

3.2 加载配置文件

func main() {
    cfg := &Config{}
    
    h, err := harvester.New(cfg).
        WithFile("config.json", harvester.JSON).
        Create()
    if err != nil {
        log.Fatalf("failed to create harvester: %v", err)
    }

    if err := h.Harvest(context.Background()); err != nil {
        log.Fatalf("failed to harvest config: %v", err)
    }

    fmt.Printf("Config loaded: %+v\n", cfg)
}

4. 动态配置与 Consul 集成

4.1 初始化 Consul 客户端

import "github.com/hashicorp/consul/api"

func getConsulClient() (*api.Client, error) {
    config := api.DefaultConfig()
    config.Address = "127.0.0.1:8500" // Consul 地址
    return api.NewClient(config)
}

4.2 使用 Harvester 从 Consul 加载配置

func main() {
    consulClient, err := getConsulClient()
    if err != nil {
        log.Fatal(err)
    }

    cfg := &Config{}
    
    h, err := harvester.New(cfg).
        WithConsulSeed("myapp/config", consulClient).
        WithConsulMonitor("myapp/config", consulClient, 5*time.Second).
        Create()
    if err != nil {
        log.Fatal(err)
    }

    if err := h.Harvest(context.Background()); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Initial config from Consul: %+v\n", cfg)

    // 监听配置变更
    go func() {
        for change := range h.Changes() {
            fmt.Printf("Config changed: %+v\n", change)
        }
    }()

    // 保持程序运行
    select {}
}

5. 高级功能

5.1 多配置源优先级

Harvester 支持多配置源,优先级如下:

  1. 环境变量
  2. Consul KV
  3. 配置文件
  4. 结构体中的 seed 值
h, err := harvester.New(cfg).
    WithFile("config.json", harvester.JSON).
    WithConsulSeed("myapp/config", consulClient).
    WithEnvVarPrefix("MYAPP").
    Create()

5.2 自定义配置变更处理器

h, err := harvester.New(cfg).
    WithChangeHandler(func(cfg interface{}) {
        fmt.Println("Configuration was changed:", cfg)
        // 在这里可以执行热更新逻辑
    }).
    Create()

6. 最佳实践

  1. 配置验证:在 ChangeHandler 中添加配置验证逻辑
  2. 优雅降级:当 Consul 不可用时回退到本地配置
  3. 敏感信息:考虑使用 Vault 而非 Consul 存储敏感配置
  4. 性能考虑:合理设置监控间隔,避免频繁检查

7. 完整示例

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/beatlabs/harvester"
	"github.com/hashicorp/consul/api"
)

type Config struct {
	Server struct {
		Host string `seed:"localhost" env:"SERVER_HOST" consul:"host" json:"host"`
		Port int    `seed:"8080" env:"SERVER_PORT" consul:"port" json:"port"`
	} `json:"server"`
	LogLevel string `seed:"info" env:"LOG_LEVEL" consul:"log_level" json:"log_level"`
}

func main() {
	// 初始化 Consul 客户端
	consulClient, err := api.NewClient(api.DefaultConfig())
	if err != nil {
		log.Fatalf("failed to create consul client: %v", err)
	}

	cfg := &Config{}

	// 创建 Harvester 实例
	h, err := harvester.New(cfg).
		WithFile("config.json", harvester.JSON).          // 本地配置文件
		WithConsulSeed("myapp/config", consulClient).    // 初始从 Consul 加载
		WithConsulMonitor("myapp/config", consulClient, 10*time.Second). // 监控变更
		WithChangeHandler(func(c interface{}) {
			fmt.Println("Configuration changed:", c)
			// 在这里可以执行热更新逻辑
		}).
		Create()
	if err != nil {
		log.Fatalf("failed to create harvester: %v", err)
	}

	// 首次加载配置
	if err := h.Harvest(context.Background()); err != nil {
		log.Fatalf("failed to harvest config: %v", err)
	}

	fmt.Printf("Initial config: %+v\n", cfg)

	// 保持程序运行并监听配置变更
	select {}
}

Harvester 为 Go 应用程序提供了强大而灵活的配置管理能力,特别是与 Consul 的集成使得分布式环境下的配置管理变得更加简单高效。

回到顶部