部署etcd
- 创建用于挂载数据的文件夹
mkdir data
- 同级目录下边下docker-compose.yml
services:
etcd:
container_name: etcd-s1
image: bitnami/etcd:latest
environment:
- ETCD_NAME=etcd-s1
- ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
- ETCD_INITIAL_ADVERTISE_PEER_URLS=http://0.0.0.0:2380
- ETCD_INITIAL_CLUSTER=etcd-s1=http://0.0.0.0:2380
- ETCD_INITIAL_CLUSTER_STATE=new
- ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
- ETCD_AUTO_TLS=false
- ETCD_CLIENT_CERT_AUTH=false
- ETCD_ROOT_PASSWORD=Password # root账号密码
- ALLOW_NONE_AUTHENTICATION=no # 开启认证
volumes:
- ./data:/bitnami/etcd
- "/etc/localtime:/etc/localtime:ro"
ports:
- 2379:2379
- 2380:2380
restart: always
- 在服务器供应商的平台开放2379、2380端口
将go中的配置文件放入配置中心
为了方便,这里采用了可视化应用来存储配置
- 安装可视化工具
vscode安装Database Client JDBC插件,并连接上etcd - 获取etcd依赖
如果etcd版本是3.5以上的用这个
如果还是报版本错误,试试用这个go get "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/clientv3"
- 利用代码将项目中的配置文件转为json数据存入etcd
cli, err = clientv3.New(clientv3.Config{ Endpoints: []string{"服务器ip:2379"}, DialTimeout: 5 * time.Second, Username: "root", Password: "Password", }) if err != nil { ... } ctx := context.Background() configKey := "config" // 将配置转成json,存入etcd。注意,这里的config就是你原来程序通过其他方式获取读取的配置文件对象 configJSON, err := json.MarshalIndent(config, "", "") if err != nil{ ... } // 存入etcd中 _,err := cli.Put(ctx,configKey,string(configJSON)) if err != nil{ .... }
- 启动项目时读取配置
步骤3的代码只是用你将配置文件放入etcd中,后面就不需要用到了,我们将直接中etcd中获取配置
func loadConfigFormEtcdCli(cli *clientv3.Client) (config *configs.Config, err error) {
ctx := context.Background()
config = &configs.Config{}
configKey := "config"
getResp, err := cli.Get(ctx, configKey)
if err != nil {
log.Fatalf("获取配置失败:%v", err)
return nil, err
}
if len(getResp.Kvs) == 0 {
log.Fatalf("配置不存在:%s", configKey)
return nil, errors.New("配置不存在")
}
err = json.Unmarshal(getResp.Kvs[0].Value, config)
if err != nil {
log.Fatalf("转化配置错误:%v", err)
} else {
log.Printf("配置更新:%v", config)
}
go watchConfig(cli, configKey, config)
return
}
func watchConfig(cli *clientv3.Client, key string, config *configs.Config) {
rch := cli.Watch(context.Background(), key)
for wresp := range rch {
for _, ev := range wresp.Events {
switch ev.Type {
case clientv3.EventTypePut:
fmt.Printf("配置已更新:%s = %s\n", string(ev.Kv.Key), string(ev.Kv.Value))
err := json.Unmarshal(ev.Kv.Value, config)
if err != nil {
log.Fatalf("转化配置错误:%v", err)
} else {
log.Printf("配置更新:%v", config)
}
case clientv3.EventTypeDelete:
fmt.Printf("配置已删除:%s\n", string(ev.Kv.Key))
}
}
}
}