基于Golang客户端实现Nacos服务注册发现和配置管理
背景
最近需要把Golang实现的一个web项目集成到基于Spring Cloud Alibaba的微服务体系中,走Spring Cloud Gateway网关路由实现统一的鉴权入口。
软件版本
组件名称 | 组件版本 |
---|---|
Nacos | 2.2.0 |
Go | 1.21.0 |
Gin | v1.9.1 |
Nacos-sdk-go | v2.2.5 |
Spring Cloud | 2021.0.2 |
Spring Cloud Alibaba | 2021.0.1.0 |
服务注册发现
项目图示
服务注册和发现
Golang客户端的注册发现使用的Nacos官方仓库里面的一个实现:https://github.com/nacos-group/nacos-sdk-go,我这边的实现大多数也是参考的官方提供的样例。
首先,初始化clientConfig和serverConfig的配置
sc := []constant.ServerConfig{*constant.NewServerConfig("localhost", 8848, constant.WithContextPath("/nacos")),}cc := *constant.NewClientConfig(constant.WithNamespaceId("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"),constant.WithTimeoutMs(5000),constant.WithNotLoadCacheAtStart(true),constant.WithLogDir("/tmp/nacos/log"),constant.WithCacheDir("/tmp/nacos/cache"),constant.WithUsername("nacos"),constant.WithPassword("nacos"),)
创建服务发现客户端
client, _ := clients.NewNamingClient(vo.NacosClientParam{ClientConfig:&cc,ServerConfigs: sc,},)
服务注册
// 注册服务registerServiceInstance(client, vo.RegisterInstanceParam{Ip:getHostIp(),Port:8777,ServiceName: ServiceName,Weight:10,Enable:true,Healthy: true,Ephemeral: true,})// 注册服务func registerServiceInstance(nacosClient naming_client.INamingClient, param vo.RegisterInstanceParam) {success, err := nacosClient.RegisterInstance(param)if !success || err != nil {panic("register Service Instance failed!")}}// 获取本机ip地址func getHostIp() string {conn, err := net.Dial("udp", "8.8.8.8:53")if err != nil {fmt.Println("get current host ip err: ", err)return ""}addr := conn.LocalAddr().(*net.UDPAddr)ip := strings.Split(addr.String(), ":")[0]return ip}
启动服务,验证ok
客户端负载均衡
作为Go语言初学者,没有详细去了解Go中类似@LoadBalanced或者Feign的框架(后续可能会补充一下),然后我这边就是获取实例解析IP和端口信息,然后直接使用Go原生的http库进行的调用。
获取实例方法
// 获取一个健康的实例func selectOneHealthyInstance(client naming_client.INamingClient, serviceName string) (instance *model.Instance) {instances, err := client.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{ServiceName: serviceName,})if err != nil {panic("SelectOneHealthyInstance failed!")}return instances}
具体调用
func hello(c *gin.Context) {name := c.Param("name")instance := selectOneHealthyInstance(NamingClient, "server-java")url := fmt.Sprintf("http://%s:%d/hello/%s", instance.Ip, instance.Port, name)resp, _ := http.Get(url)defer resp.Body.Close()body, _ := io.ReadAll(resp.Body)c.String(http.StatusOK, string(body))}
在server-java中,提供了一个rest接口
/** * 启动类 * * @author yuanzhihao * @since 2024/3/4 */@RestController@RequestMapping@SpringBootApplicationpublic class Application {@GetMapping("/hello/{name}")public String hello(@PathVariable("name") String name) {return "Hello " + name;}public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
请求 http://localhost:8777/hello/yuan, 调用成功
配置管理
图示
第一步和注册发现一样,初始化clientConfig和serverConfig的配置,略
创建动态配置客户端
configClient, _ := clients.NewConfigClient(vo.NacosClientParam{ClientConfig:&cc,ServerConfigs: sc,},)
拉取指定data-id的配置
config, _ := ConfigClient.GetConfig(vo.ConfigParam{DataId: ServiceName,})fmt.Printf("config is " + config)
我这边写了一个rest的接口,可以指定获取某个具体配置的值
// 初始化服务端func ServerSetup() {r := gin.Default()r.GET("/hello/:name", hello)r.GET("/config", getSpecifiedConfig)r.Run(":8777")}// 获取指定的配置func getSpecifiedConfig(c *gin.Context) {param := c.DefaultQuery("name", "")config, _ := ConfigClient.GetConfig(vo.ConfigParam{DataId: ServiceName,})fmt.Printf("config is " + config)// 解析YAML数据var data map[string]interface{}err := yaml.Unmarshal([]byte(config), &data)if err != nil {fmt.Println("error unmarshalling YAML", err)}value := getValue(data, param)c.String(http.StatusOK, "param [ "+param+" ] value is "+value)}func getValue(data map[string]interface{}, keyPath string) string {keys := strings.Split(keyPath, ".")var value interface{} = datafor _, key := range keys {if v, ok := value.(map[string]interface{}); ok {value = v[key]} else {return ""}}if v, ok := value.(string); ok {return v}return fmt.Sprintf("%v", value)}
配置client-go如下
my:name: yuanage: 27city: Nanjing
调用请求 http://localhost:8777/config” />
结语
参考地址:https://github.com/nacos-group/nacos-sdk-go
代码地址:https://github.com/yzh19961031/blogDemo/tree/master/go-nacos