golang,go,博客,开源,编程
要在 Go 中使用 Viper
从 Consul
获取配置,你需要结合使用 Viper
和 Consul
客户端。Consul
是一个流行的分布式系统管理工具,用于服务发现、健康检查和配置管理。通过使用 Consul
的 Key-Value 存储功能,你可以将应用的配置存储在 Consul
中,并在应用中动态加载。
Viper
本身不直接支持 Consul
,但你可以通过 consul-api
或 consul
官方客户端与 Viper
配合使用,从 Consul
获取配置并加载到 Viper
中。
安装依赖
安装 Viper
和 Consul
客户端。
go get github.com/spf13/viper
go get github.com/hashicorp/consul/api
设置 Consul 客户端
Consul
提供了一个 Go 客户端库 consul/api
,可以通过它与 Consul
进行交互,读取存储在 Consul 中的配置。
从 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)
}
}
Consul
客户端:
api.NewClient
创建 Consul
客户端。通过配置文件中设置 Address
和 Scheme
,配置 Consul
服务的地址。Consul
中的配置:
client.KV()
获取 Consul
的 Key-Value 存储实例。kv.Get("config/app", nil)
获取 Consul
中 config/app
键下的配置。Consul
配置加载到 Viper
:
viper.SetConfigType("json")
设置配置格式为 JSON。viper.ReadConfig(pair.Value)
将从 Consul
获取的配置加载到 Viper
中。viper.GetString("app.name")
和 viper.GetInt("app.port")
获取配置项。Consul
配置变化:
Consul
中的配置,模拟配置变更的监听。Consul
中的配置),程序会自动更新 Viper
中的配置,并打印出新的配置。time.Sleep(5 * time.Second)
每隔 5 秒检查一次 Consul
中的配置。通过这种方式,你可以实时地监控 Consul
中的配置变化。如果配置发生变化,程序会更新 Viper
中的配置,并重新加载。你可以通过手动修改 Consul
中的配置来验证这一点。
例如,如果你在 Consul
中更新了 config/app
配置:
consul kv put config/app '{"app": {"name": "NewApp", "port": 9090}}'
程序会自动检测到配置的变化,并更新 Viper
中的配置。
通过结合 Viper
和 Consul
,你可以实现从 Consul
动态获取和管理配置。Viper
提供了方便的配置管理功能,而 Consul
可以作为分布式配置管理的中心,通过 KV
存储提供高效、可靠的配置存储方案。通过这种方式,你可以轻松地构建一个支持动态配置管理的系统,尤其适用于微服务架构和分布式系统。