golang,go,博客,开源,编程

viper 从etcd获取配置

Published on with 0 views and 0 comments

Viper 支持从多种来源获取配置,除了文件、环境变量、命令行标志等外,还可以通过与 etcd 集成,从 etcd 中获取配置数据。etcd 是一个高可用的分布式键值存储,通常用于存储配置和服务发现等信息。

要让 Viper 从 etcd 获取配置,你需要使用 viperetcd 的集成。虽然 Viper 本身没有直接内置 etcd 的支持,但我们可以通过一个简单的步骤将它们结合起来。

步骤

  1. 安装必要的包
    • viper 用于加载配置。
    • etcd 客户端用于从 etcd 获取配置。
go get github.com/spf13/viper
go get go.etcd.io/etcd/clientv3
  1. 连接到 etcd
    使用 etcd 客户端来连接 etcd,然后通过 Viper 加载从 etcd 获取的配置。

示例代码

以下是一个示例,展示如何从 etcd 获取配置并使用 Viper 管理这些配置。

package main

import (
	"context"
	"fmt"
	"log"
	"github.com/spf13/viper"
	"go.etcd.io/etcd/clientv3"
	"time"
)

func main() {
	// 创建一个 etcd 客户端
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"localhost:2379"}, // etcd 地址
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	// 从 etcd 获取配置
	kv := clientv3.NewKV(client)
	resp, err := kv.Get(context.Background(), "config/app", clientv3.WithPrefix()) // 获取 "config/app" 路径下的所有配置
	if err != nil {
		log.Fatal(err)
	}

	// 将 etcd 获取到的配置加载到 viper
	for _, kvPair := range resp.Kvs {
		// 假设 key 是以 "config/app" 开头的,我们将去掉这个前缀
		key := string(kvPair.Key)[len("config/"):]
		// 使用 Viper 设置配置项
		viper.Set(key, string(kvPair.Value))
	}

	// 输出从 etcd 获取的配置
	appName := viper.GetString("app.name")
	port := viper.GetInt("app.port")

	fmt.Printf("App Name: %s\n", appName)
	fmt.Printf("App Port: %d\n", port)

	// 可以动态更新配置,监控 etcd 配置变化
	watchConfig(client)
}

// watchConfig 监控 etcd 配置变化
func watchConfig(client *clientv3.Client) {
	rch := client.Watch(context.Background(), "config/app", clientv3.WithPrefix())
	for wresp := range rch {
		for _, ev := range wresp.Events {
			fmt.Printf("Event type: %s, key: %s, value: %s\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
			// 可以将新的配置加载到 viper
			viper.Set(string(ev.Kv.Key), string(ev.Kv.Value))
		}
	}
}

代码解析

  1. etcd 客户端配置
    • 使用 clientv3.New 方法连接到 etcdEndPointsetcd 的地址列表。你可以通过 DialTimeout 配置超时时间。
  2. etcd 获取配置
    • 使用 clientv3.NewKV(client) 创建 KV 操作对象,然后通过 kv.Getetcd 获取配置。
    • clientv3.WithPrefix() 表示获取 config/app 路径下所有的配置项。
  3. Viper 设置配置
    • 通过 viper.Set(key, value) 将从 etcd 获取的配置动态加载到 Viper 中。
    • 你可以将 etcd 中的配置信息映射到 Viper 的键值对中。
  4. 监控 etcd 配置变化
    • 使用 client.Watch 来监控 etcdconfig/app 路径下的配置变化,若配置发生变化,Viper 会自动更新。
  5. Viper 读取配置
    • 使用 viper.GetStringviper.GetInt 等方法来获取配置。

配置样例

假设你在 etcd 中存储了如下配置:

etcdctl put config/app.name "MyApp"
etcdctl put config/app.port "8080"

运行上面的 Go 程序后,Viper 会从 etcd 获取并打印出配置:

App Name: MyApp
App Port: 8080

配置动态更新

通过调用 client.Watch,你可以实时监控 etcd 中的配置变化。当配置发生变化时,程序会打印出变化的内容,并自动更新 viper 中的配置。

例如,假设你修改了 etcd 中的配置:

etcdctl put config/app.name "NewApp"
etcdctl put config/app.port "9090"

程序会捕获到这个变化并打印:

Event type: PUT, key: config/app.name, value: NewApp
Event type: PUT, key: config/app.port, value: 9090

总结

  • Viper 可以通过自定义方式从 etcd 中获取配置,虽然它没有直接支持 etcd,但通过 clientv3 库获取配置,然后将配置加载到 Viper 中,依然可以实现强大的配置管理。
  • 动态配置:通过 etcdWatch 功能,可以实时更新配置,并让 Viper 动态加载新的配置,支持热加载。

标题:viper 从etcd获取配置
作者:mooncakeee
地址:http://blog.dd95828.com/articles/2025/01/07/1736215405566.html
联系:scotttu@163.com