记一次升级 Viper、ETCD V3操作Toml

前一阵子碰到Go写的一项目,使用viper和ETCD进行Toml文件的存储与写入。在当我安装新版本的ETCD和升级Go依赖包之后出现了不兼容的问题。旧版viper为1.10版本,使用github.com/coreos/go-etcd v2.0.0+incompatible 作为请求包。看了源码之后发现新的版本中废弃掉了很多内容,所以既然升级了ETCD,那不如将逻辑重写了。
目前使用的包版本
github.com/spf13/viper v1.15.0
go.etcd.io/etcd/client/v3 v3.5.9

代码如下:

go 复制代码
package main

import (
	"bytes"
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"github.com/spf13/viper"
	"io/ioutil"
	"log"
	"os"
	"time"

	_ "github.com/spf13/viper/remote"
	clientv3 "go.etcd.io/etcd/client/v3"
)

type etcdClient struct {
	cli *clientv3.Client
}

func initClient(endpoint string) *etcdClient {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
    
    // 这里的证书只是释意,我没有配置证书下面跳过验证了
	cert, err := tls.LoadX509KeyPair("healthcheck-client.crt", "healthcheck-client.key")
	if err != nil {
		log.Fatalf("Failed to load client cert and key: %v", err)
	}

	caCert, err := ioutil.ReadFile("ca.crt")
	if err != nil {
		log.Fatalf("Failed to read ca certificate: %v", err)
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)

	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{endpoint},
		DialTimeout: 10 * time.Second,
		TLS: &tls.Config{
			Certificates:       []tls.Certificate{cert},
			RootCAs:            caCertPool,
			InsecureSkipVerify: false,
		},
	})
	if err != nil {
		log.Fatalf("Failed to connect to etcd: %v", err)
	}
	fmt.Println("init client...")
	return &etcdClient{
		cli: cli,
	}
}

func (cli *etcdClient) Put(key string, fileName string) {

	fmt.Println("write config to etcd...")
	data, err := os.ReadFile(fileName)
	if err != nil {
		log.Fatalf("Failed to read config file: %v", err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	_, err = cli.cli.Put(ctx, key, string(data))
	cancel()
	if err != nil {
		log.Fatalf("Failed to write config to etcd: %v", err)
	}
}

func (cli *etcdClient) Get(key string) {
	fmt.Println("get config from etcd...")

	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	resp, err := cli.cli.Get(ctx, key)
	cancel()
	if err != nil {
		log.Fatalf("Failed to get config from etcd: %v", err)
	}

	viper.SetConfigType("toml")
	if len(resp.Kvs) > 0 {
		err = viper.ReadConfig(bytes.NewBuffer(resp.Kvs[0].Value))
		if err != nil {
			log.Fatalf("Failed to read configuration: %v", err)
		}
	} else {
		log.Fatalf("No config found in ETCD")
	}

	fmt.Println("读取的配置信息:", viper.Get("god_job.repo.k8s"))
}

func viperDemo(endpoint, key string) {
	v := viper.New()

	v.SetConfigType("toml")
	err := v.AddRemoteProvider("etcd3", endpoint, key)
	if err != nil {
		log.Fatalf("Failed to add remote provider: %v", err)
	}

	err = v.ReadRemoteConfig()
	fmt.Println("读取的配置信息:", v.Get("god_job.repo.k8s"))
}

func main() {
	fileName := "conf.dev.toml"
	keyString := "/dev/conf.dev.toml"
	endpoint := "http://127.0.0.1:23791"
	cli := initClient(endpoint)
	cli.Put(keyString, fileName)
	cli.Get(keyString)
	cli.cli.Close()

	viperDemo(endpoint, keyString)
}
注意点!

1. Viper包中是不支持配置证书的,旧版remote可以绕过HTTPS,(目前我没找到,有大佬可以在评论区告诉我),所以如果ETCD有证书的话建议先读出来然后使用Viper解析。
2. ETCD V2 版本的API存入的数据使用v3是读不出来的,也就是说v2存v2读,v3存v3读。

相关推荐
野犬寒鸦7 分钟前
Pipeline功能实现Redis批处理(项目批量查询点赞情况的应用)
java·服务器·数据库·redis·后端·缓存
꧁༺摩༒西༻꧂13 分钟前
Spring Boot Actuator 监控功能的简介及禁用
java·数据库·spring boot
程序员JerrySUN21 分钟前
当前主流GPU全景讲解:架构、功能与应用方向
数据库·人工智能·驱动开发·redis·缓存·架构
__Smile°21 分钟前
kubeadm-k8s 中的 etcd 备份与恢复
数据库·docker·云原生·容器·kubernetes·etcd
Runing_WoNiu1 小时前
最佳左前缀法则(Optimal Left-Prefix Rule)
数据库·mysql
IvorySQL1 小时前
如何使用 pg_rman 进行 PostgreSQL 的备份与恢复
数据库
Tapdata2 小时前
一文了解增量物化视图维护(IVM):原理、演化与实践落地
数据库
码间舞2 小时前
IndexDB适用于什么场景?如何使用IndexDB?
前端·javascript·数据库
lovebugs2 小时前
Kubernetes中高效获取Java应用JVM参数的终极指南
后端·docker·kubernetes
叫我:松哥2 小时前
基于Python的实习僧招聘数据采集与可视化分析,使用matplotlib进行可视化
开发语言·数据库·python·课程设计·matplotlib·文本挖掘