前言
在网上没有找到 Viper 搭配 Nacos 配置中心的合适例子,大多是单独的 Viper 或者 SpringCloud Nacos 配置,于是就自己实现了一个简单的适用 Go 的 Example,希望可以给大家提供一个参考。
项目地址在这里,建议 clone 下来对着代码跟着本文走以获得更好的阅读体验。
注意:本例的 Nacos 等相关配置进行了简化,更多配置请参考官方文档。
思路
Example 提供了两种思路:
-
思路一
较为常见的一种思路
- 在Nacos 中配置好项目所需配置,例如 MySQL 等;
- 在项目本地配置好 Nacos 的地址端口等信息;
- 建立连接获取第一步配置在 Naocs 中的 MySQL 等配置;
- 监听 Nacos 配置变化
这种思路对应 Example 中的 remote 模块
-
思路二
奇奇怪怪的思路
- 在项目本地配置好所有所需配置(Nacos, MySQL等)
- 项目启动将本地配置发布到 Nacos;
- 监听 Nacos 配置,如果发生变化应用到本地配置文件;
这种思路对应 Example 中的 local 模块
代码实现
思路一
-
配置好配置文件及其对应的映射结构体
配置结构体,由于 Example 中在 Nacos 上配置了 MySQL 所以这里需要配置 MySQL 结构体,详见 readme
type Config struct { Nacos NacosConfig MySQL MySQLConfig } type NacosConfig struct { Host string `json:"host"` Port int `json:"port"` DataId string `json:"dataId"` Group string `json:"group"` } type MySQLConfig struct { Host string `json:"host"` Port int `json:"port"` Username string `json:"username"` Password string `json:"password"` Database string `json:"database"` }配置文件
nacos: host: 127.0.0.1 port: 8848 dataid: example-remote group: example-remote -
使用 Viper 读取本地 Nacos 配置
viper.SetConfigFile(configPath) // read nacosConfig err := viper.ReadInConfig() if err != nil { log.Fatalf("viper read nacosConfig failed: %v", err) } err = viper.Unmarshal(&config) if err != nil { log.Fatalf("viper unmarshal nacosConfig failed: %v", err) } viper.WatchConfig() -
配置 Nacos Server 和 Client 配置
// server nacosConfig sc := []constant.ServerConfig{ *constant.NewServerConfig(config.Nacos.Host, uint64(config.Nacos.Port), constant.WithContextPath("/nacos")), } // client nacosConfig cc := *constant.NewClientConfig( constant.WithNamespaceId(""), ) -
配置 Nacos 配置管理客户端
// client client, err := clients.NewConfigClient( vo.NacosClientParam{ ClientConfig: &cc, ServerConfigs: sc, }, ) if err != nil { log.Fatalf("create nacos nacosConfig client failed: %v", err) } -
获取 Nacos 中的配置并利用 Viper 对结构体进行赋值
content, err := client.GetConfig(vo.ConfigParam{ DataId: config.Nacos.DataId, Group: config.Nacos.Group, }) err = viper.ReadConfig(bytes.NewBufferString(content)) if err != nil { log.Fatal("viper read config failed: ", err) } err = viper.Unmarshal(&config) if err != nil { log.Fatalf("viper unmarshal config failed: %v", err) } -
监听 Nacos 配置变化,如果发生变化利用 Viper 应用到本地
err = client.ListenConfig(vo.ConfigParam{ DataId: config.Nacos.DataId, Group: config.Nacos.Group, OnChange: func(namespace, group, dataId, data string) { err := viper.ReadConfig(bytes.NewBufferString(data)) if err != nil { log.Printf("viper read config failed: %v", err) } err = viper.Unmarshal(&config) if err != nil { log.Printf("viper unmarshal config failed: %v", err) } log.Println(config) }, }) if err != nil { log.Fatalf("nacos listen config failed: %v", err) }
思路二
-
在本地配置文件配置好所有配置及其对应的结构体
配置结构体
type Config struct { Service ServiceConfig Nacos NacosConfig MySQL MySQLConfig } type ServiceConfig struct { Name string `json:"name"` Addr string `json:"addr"` } type NacosConfig struct { Host string `json:"host"` Port int `json:"port"` DataId string `json:"dataId"` Group string `json:"group"` } type MySQLConfig struct { Host string `json:"host"` Port int `json:"port"` Username string `json:"username"` Password string `json:"password"` Database string `json:"database"` }配置文件
mysql: database: example-local host: 127.0.0.1 password: 114514 port: 3306 username: root nacos: dataid: example-local group: example-local host: 127.0.0.1 port: 8848 service: addr: 127.0.0.1:8080 name: example-local -
利用 Viper 读取配置文件
viper.SetConfigFile(configPath) // read config err := viper.ReadInConfig() if err != nil { log.Fatalf("viper read config failed: %v", err) } err = viper.Unmarshal(&config) if err != nil { log.Fatalf("viper unmarshal config failed: %v", err) } viper.WatchConfig() -
配置 Nacos Server 和 Client
// server config sc := []constant.ServerConfig{ *constant.NewServerConfig(config.Nacos.Host, uint64(config.Nacos.Port), constant.WithContextPath("/nacos")), } // client config cc := *constant.NewClientConfig( constant.WithNamespaceId(""), ) -
配置 Nacos 配置管理客户端
// client client, err := clients.NewConfigClient( vo.NacosClientParam{ ClientConfig: &cc, ServerConfigs: sc, }, ) if err != nil { log.Fatalf("create nacos config client failed: %v", err) } -
将本地配置发布到 Nacos
jsonBytes, err := json.Marshal(config) if err != nil { log.Fatalf("marshal json config failed: %v", err) } _, err = client.PublishConfig(vo.ConfigParam{ DataId: config.Nacos.DataId, Group: config.Nacos.Group, Content: string(jsonBytes), }) if err != nil { log.Fatalf("nacos publish config failed: %v", err) } -
监听 Nacos 配置变化,发生变化利用 Viper 应用到本地配置文件
err = client.ListenConfig(vo.ConfigParam{ DataId: config.Nacos.DataId, Group: config.Nacos.Group, OnChange: func(namespace, group, dataId, data string) { viper.SetConfigType(configType) err := viper.ReadConfig(bytes.NewBufferString(data)) if err != nil { log.Printf("viper read config failed: %v", err) } err = viper.WriteConfigAs(configPath) log.Println("apply new config to local") if err != nil { log.Printf("viper write config failed: %v", err) } }, }) if err != nil { log.Fatalf("nacos listen config failed: %v", err) }
运行
思路一
启动 Nacos
docker-compose up
配置 Nacos
在浏览器上访问 127.0.0.1:8848/nacos
默认用户名和密码为 nacos
添加 MySQL 配置
- Data ID:
example-remote - Group:
example-remote
mysql:
host: 127.0.0.1
port: 3306
username: root
password: 114514
database: example-remote
启动
cd remote
go run .
动态配置
在 Nacos 更改 MySQL 配置,观察本地日志输出。
注意:程序默认 90s 后停止,请按需配置
思路二
启动 Nacos
docker-compose up
启动
cd local
go run .
动态配置
在浏览器上访问 127.0.0.1:8848/nacos
默认用户名和密码为 nacos
- 查看本地配置发布情况
- 更改 Nacos 配置,观察本地配置文件变化
注意:程序默认 90s 后停止,请按需配置
总结
以上就是本篇文章的所有内容了,希望可以帮助到你,欢迎 Star,如果有问题或疑问欢迎在评论区指出或者私聊,以上ww