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

viper从consul获取配置

Published on with 0 views and 0 comments

要在 Go 中使用 ViperConsul 获取配置,你需要结合使用 ViperConsul 客户端。Consul 是一个流行的分布式系统管理工具,用于服务发现、健康检查和配置管理。通过使用 Consul 的 Key-Value 存储功能,你可以将应用的配置存储在 Consul 中,并在应用中动态加载。

Viper 本身不直接支持 Consul,但你可以通过 consul-apiconsul 官方客户端与 Viper 配合使用,从 Consul 获取配置并加载到 Viper 中。

步骤

  1. 安装依赖
    安装 ViperConsul 客户端。

    go get github.com/spf13/viper
    go get github.com/hashicorp/consul/api
    
  2. 设置 Consul 客户端
    Consul 提供了一个 Go 客户端库 consul/api,可以通过它与 Consul 进行交互,读取存储在 Consul 中的配置。

  3. 从 Consul 获取配置并加载到 Viper
    假设在 Consul 中存储了如下配置数据:

    {
      "app": {
        "name": "MyApp",
        "port": 8080
      }
    }
    

    以下是一个从 Consul 获取配置并将其加载到 Viper 中的 Go 示例。

示例代码

package main

import (
	"fmt"
	"log"
	"github.com/spf13/viper"
	"github.com/hashicorp/consul/api"
	"time"
)

func main() {
	// 创建 Consul 客户端配置
	config := &api.Config{
		Address: "127.0.0.1:8500", // Consul 服务器地址
		Scheme:  "http",
	}

	// 创建 Consul 客户端
	client, err := api.NewClient(config)
	if err != nil {
		log.Fatalf("Error creating Consul client: %v", err)
	}

	// 获取 Consul 中的配置
	kv := client.KV()

	// 假设配置的 Key 为 "config/app"
	pair, _, err := kv.Get("config/app", nil)
	if err != nil {
		log.Fatalf("Error getting key from Consul: %v", err)
	}

	// 打印 Consul 配置的值
	fmt.Println("Consul Config Value:")
	fmt.Println(string(pair.Value))

	// 将从 Consul 获取的配置加载到 Viper
	viper.SetConfigType("json") // 假设配置文件为 JSON 格式
	err = viper.ReadConfig(pair.Value)
	if err != nil {
		log.Fatalf("Error loading config into Viper: %v", err)
	}

	// 获取配置
	appName := viper.GetString("app.name")
	port := viper.GetInt("app.port")

	// 打印配置
	fmt.Printf("App Name: %s\n", appName)
	fmt.Printf("App Port: %d\n", port)

	// 监听 Consul 配置变更
	err = watchConfig(client, "config/app")
	if err != nil {
		log.Fatalf("Error watching config: %v", err)
	}
}

// watchConfig 监听 Consul 配置变化
func watchConfig(client *api.Client, key string) error {
	kv := client.KV()

	// 监听配置变化
	// 这里使用一个简单的循环和 blocking 查询来模拟监听
	for {
		// 获取最新的配置
		pair, _, err := kv.Get(key, nil)
		if err != nil {
			return fmt.Errorf("error getting key from Consul: %v", err)
		}

		// 如果配置变化
		if pair != nil {
			// 打印配置
			fmt.Printf("Updated Config Value from Consul: %s\n", string(pair.Value))

			// 更新 Viper 中的配置
			viper.SetConfigType("json")
			err := viper.ReadConfig(pair.Value)
			if err != nil {
				return fmt.Errorf("error reading config into Viper: %v", err)
			}

			// 打印更新后的配置
			appName := viper.GetString("app.name")
			port := viper.GetInt("app.port")
			fmt.Printf("Updated App Name: %s\n", appName)
			fmt.Printf("Updated App Port: %d\n", port)
		}

		// 每隔 5 秒查询一次
		time.Sleep(5 * time.Second)
	}
}

代码解析

  1. 创建 Consul 客户端
    • 使用 api.NewClient 创建 Consul 客户端。通过配置文件中设置 AddressScheme,配置 Consul 服务的地址。
  2. 获取 Consul 中的配置
    • 通过 client.KV() 获取 Consul 的 Key-Value 存储实例。
    • 使用 kv.Get("config/app", nil) 获取 Consulconfig/app 键下的配置。
  3. Consul 配置加载到 Viper
    • 使用 viper.SetConfigType("json") 设置配置格式为 JSON。
    • 使用 viper.ReadConfig(pair.Value) 将从 Consul 获取的配置加载到 Viper 中。
  4. 获取配置
    • 使用 viper.GetString("app.name")viper.GetInt("app.port") 获取配置项。
  5. 监听 Consul 配置变化
    • 通过一个简单的循环,不断查询 Consul 中的配置,模拟配置变更的监听。
    • 如果配置发生变化(假设你手动修改了 Consul 中的配置),程序会自动更新 Viper 中的配置,并打印出新的配置。
  6. 每隔 5 秒查询一次
    • 使用 time.Sleep(5 * time.Second) 每隔 5 秒检查一次 Consul 中的配置。

6. 配置变更的监听

通过这种方式,你可以实时地监控 Consul 中的配置变化。如果配置发生变化,程序会更新 Viper 中的配置,并重新加载。你可以通过手动修改 Consul 中的配置来验证这一点。

例如,如果你在 Consul 中更新了 config/app 配置:

consul kv put config/app '{"app": {"name": "NewApp", "port": 9090}}'

程序会自动检测到配置的变化,并更新 Viper 中的配置。

7. 总结

通过结合 ViperConsul,你可以实现从 Consul 动态获取和管理配置。Viper 提供了方便的配置管理功能,而 Consul 可以作为分布式配置管理的中心,通过 KV 存储提供高效、可靠的配置存储方案。通过这种方式,你可以轻松地构建一个支持动态配置管理的系统,尤其适用于微服务架构和分布式系统。


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