Go微服务: Nacos的搭建和基础API的使用

Nacos 概述

  • 文档:https://nacos.io/docs/latest/what-is-nacos/
  • 搭建:https://nacos.io/docs/latest/quickstart/quick-start-docker/
  • 有很多种搭建方式,我们这里使用 docker 来搭建

Nacos 的搭建

  • 这里,我们选择单机模式,简单些,仅仅做一些示例
  • 创建 docker-compose.yaml
    version: "3.8"
    services:
      nacos:
        image: nacos/nacos-server:latest
        container_name: nacos-standalone
        env_file:
          - ./config.env
        volumes:
          - ./standalone-logs/:/home/nacos/logs
        ports:
          - "8848:8848"
          - "9848:9848"
        restart: always
    
    • 这里我们可知,依赖 standalone-logs 目录和 config.env 文件
    • 前者创建即可,后者我们来看下
  • config.env
    PREFER_HOST_MODE=hostname  
    MODE=standalone  
    NACOS_AUTH_IDENTITY_KEY=serverIdentity  
    NACOS_AUTH_IDENTITY_VALUE=security  
    NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
    
  • 以上这些,都是基于官方文档中,改造过来的
  • 先拉取镜像 $ docker pull nacos/nacos-server
  • 运行 $ docker-compose up -d
  • 访问:http://127.0.0.1:8848/nacos/
  • 用户名/密码:nacos/nacos, 登录后可进行自行修改
  • 创建一个命名空间, 命名为: dev,创建完成后会生成一个命名空间ID
  • 在配置列表的 dev 下,新建配置
    • Data ID: test.json
    • Group: tt
    • 配置内容: { "name": "abc" }

Nacos V2 功能展示

  • 文档:https://github.com/nacos-group/nacos-sdk-go
  • 文档上面有相关示例和说明

1 )注册服务和获取服务

package main

import (
	"fmt"
	"time"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
)

func registerServiceInstance(client naming_client.INamingClient, param vo.RegisterInstanceParam) {
	success, err := client.RegisterInstance(param)
	if !success || err != nil {
		panic("RegisterServiceInstance failed!" + err.Error())
	}
	fmt.Printf("RegisterServiceInstance,param:%+v,result:%+v \n\n", param, success)
}

func getService(client naming_client.INamingClient, param vo.GetServiceParam) {
	service, err := client.GetService(param)
	if err != nil {
		panic("GetService failed!" + err.Error())
	}
	fmt.Printf("GetService,param:%+v, result:%+v \n\n", param, service)
}

func getAllService(client naming_client.INamingClient, param vo.GetAllServiceInfoParam) {
	service, err := client.GetAllServicesInfo(param)
	if err != nil {
		panic("GetAllService failed!")
	}
	fmt.Printf("GetAllService,param:%+v, result:%+v \n\n", param, service)
}

func main() {
	//create ServerConfig
	sc := []constant.ServerConfig{
		*constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")),
	}

	//create ClientConfig
	cc := *constant.NewClientConfig(
		constant.WithNamespaceId("ff2e8758-33c1-4a88-8005-142cbee91be9"),
		constant.WithTimeoutMs(5000),
		constant.WithNotLoadCacheAtStart(true),
		constant.WithLogDir("nacos/log"),
		constant.WithCacheDir("nacos/cache"),
		constant.WithLogLevel("debug"),
	)

	// create naming client
	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &cc,
			ServerConfigs: sc,
		},
	)

	if err != nil {
		panic(err)
	}

	// Register
	registerServiceInstance(client, vo.RegisterInstanceParam{
		Ip:          "127.0.0.1",
		Port:        8848,
		ServiceName: "demo.go",
		GroupName:   "tt",
		// ClusterName: "cluster-a",
		Weight:    10,
		Enable:    true,
		Healthy:   true,
		Ephemeral: true,
		Metadata:  map[string]string{"idc": "shanghai"},
	})

	time.Sleep(1 * time.Second)

	//Get service with serviceName, groupName, clusters
	getService(client, vo.GetServiceParam{
		ServiceName: "demo.go",
		GroupName:   "tt",
		// Clusters:    []string{"cluster-a"},
	})

	//wait for client pull change from server
	time.Sleep(3 * time.Second)

	//GeAllService will get the list of service name
	//NameSpace default value is public.If the client set the namespaceId, NameSpace will use it.
	//GroupName default value is DEFAULT_GROUP
	getAllService(client, vo.GetAllServiceInfoParam{
		GroupName: "tt",
		PageNo:    1,
		PageSize:  10,
	})
	time.Sleep(300000 * time.Second)
}
  • 上面示例实现了注册服务,获取服务的示例, 后续如果需要,可以进行封装
  • 效果如下

可见注册和获取成功

2 )服务相关的其他功能

2.1 批量注册示例

//BatchRegister
batchRegisterServiceInstance(client, vo.BatchRegisterInstanceParam{
	ServiceName: "demo.go",
	GroupName:   "tt",
	Instances: []vo.RegisterInstanceParam{{
		Ip:          "127.0.0.1",
		Port:        8848,
		Weight:      10,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
		// ClusterName: "cluster-a",
		Metadata:    map[string]string{"idc": "shanghai"},
	}, {
		Ip:          "127.0.0.1",
		Port:        8848,
		Weight:      7,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
		// ClusterName: "cluster-a",
		// Metadata:    map[string]string{"idc": "shanghai"},
	}},
})

func batchRegisterServiceInstance(client naming_client.INamingClient, param vo.BatchRegisterInstanceParam) {
	success, err := client.BatchRegisterInstance(param)
	if !success || err != nil {
		panic("BatchRegisterServiceInstance failed!" + err.Error())
	}
	fmt.Printf("BatchRegisterServiceInstance,param:%+v,result:%+v \n\n", param, success)
}

2.2 更新服务

func updateServiceInstance(client naming_client.INamingClient, param vo.UpdateInstanceParam) {
	success, err := client.UpdateInstance(param)
	if !success || err != nil {
		panic("UpdateInstance failed!" + err.Error())
	}
	fmt.Printf("UpdateServiceInstance,param:%+v,result:%+v \n\n", param, success)
}

updateServiceInstance(client, vo.UpdateInstanceParam{
	Ip:          "127.0.0.1", //update ip
	Port:        8848,
	ServiceName: "demo.go",
	GroupName:   "tt",
	// ClusterName: "cluster-a",
	Weight:      10,
	Enable:      true,
	Healthy:     true,
	Ephemeral:   true,
	Metadata:    map[string]string{"idc": "beijing1"}, //update metadata
})

2.3 订阅服务和取消服务订阅

func subscribe(client naming_client.INamingClient, param *vo.SubscribeParam) {
	client.Subscribe(param)
}

func unSubscribe(client naming_client.INamingClient, param *vo.SubscribeParam) {
	client.Unsubscribe(param)
}

//Subscribe key=serviceName+groupName+cluster
//Note:We call add multiple SubscribeCallback with the same key.
subscribeParam := &vo.SubscribeParam{
	ServiceName: "demo.go",
	GroupName:   "tt",
	SubscribeCallback: func(services []model.Instance, err error) {
		fmt.Printf("callback return services:%s \n\n", util.ToJsonString(services))
	},
}
subscribe(client, subscribeParam)

// UnSubscribe
unSubscribe(client, subscribeParam)

2.4 获取服务实例

func selectAllInstances(client naming_client.INamingClient, param vo.SelectAllInstancesParam) {
	instances, err := client.SelectAllInstances(param)
	if err != nil {
		panic("SelectAllInstances failed!" + err.Error())
	}
	fmt.Printf("SelectAllInstance,param:%+v, result:%+v \n\n", param, instances)
}

//SelectAllInstance
//GroupName=DEFAULT_GROUP
selectAllInstances(client, vo.SelectAllInstancesParam{
	ServiceName: "demo.go",
	GroupName:   "tt",
	Clusters:    []string{"cluster-a"},
})


func selectInstances(client naming_client.INamingClient, param vo.SelectInstancesParam) {
	instances, err := client.SelectInstances(param)
	if err != nil {
		panic("SelectInstances failed!" + err.Error())
	}
	fmt.Printf("SelectInstances,param:%+v, result:%+v \n\n", param, instances)
}

//SelectInstances only return the instances of healthy=${HealthyOnly},enable=true and weight>0
//ClusterName=DEFAULT,GroupName=DEFAULT_GROUP
selectInstances(client, vo.SelectInstancesParam{
	ServiceName: "demo.go",
	GroupName:   "tt",
	// Clusters:    []string{"cluster-a"},
	HealthyOnly: true,
})

func selectOneHealthyInstance(client naming_client.INamingClient, param vo.SelectOneHealthInstanceParam) {
	instances, err := client.SelectOneHealthyInstance(param)
	if err != nil {
		panic("SelectOneHealthyInstance failed!")
	}
	fmt.Printf("SelectOneHealthyInstance,param:%+v, result:%+v \n\n", param, instances)
}

//SelectOneHealthyInstance return one instance by WRR strategy for load balance
//And the instance should be health=true,enable=true and weight>0
//ClusterName=DEFAULT,GroupName=DEFAULT_GROUP
selectOneHealthyInstance(client, vo.SelectOneHealthInstanceParam{
	ServiceName: "demo.go",
	GroupName:   "tt",
	// Clusters:    []string{"cluster-a"},
})

3 ) 配置相关

  • 先在 nacos 的配置文件中,进行数据的配置
  • 再进行编码获取

    package main
    
    import (
    	"fmt"
    	"time"
    
    	"github.com/nacos-group/nacos-sdk-go/v2/clients"
    	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
    	"github.com/nacos-group/nacos-sdk-go/v2/vo"
    )
    
    func main() {
    	//create ServerConfig
    	sc := []constant.ServerConfig{
    		*constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")),
    	}
    	//create ClientConfig
    	cc := *constant.NewClientConfig(
    		constant.WithNamespaceId("ff2e8758-33c1-4a88-8005-142cbee91be9"),
    		constant.WithTimeoutMs(5000),
    		constant.WithNotLoadCacheAtStart(true),
    		constant.WithLogDir("nacos/log"),
    		constant.WithCacheDir("nacos/cache"),
    		constant.WithLogLevel("debug"),
    	)
    	// create config client
    	client, err := clients.NewConfigClient(
    		vo.NacosClientParam{
    			ClientConfig:  &cc,
    			ServerConfigs: sc,
    		},
    	)
    	if err != nil {
    		panic(err)
    	}
    
    	//get config
    	content, err := client.GetConfig(vo.ConfigParam{
    		DataId: "test.json",
    		Group:  "tt",
    	})
    	fmt.Println("GetConfig,config :" + content)
    	time.Sleep(100000000 * time.Second)
    }
    
  • 查看输出

4 )配置相关的其他功能

4.1 监听配置

//Listen config change,key=dataId+group+namespaceId.
err = client.ListenConfig(vo.ConfigParam{
	DataId: "test.json",
	Group:  "tt",
	OnChange: func(namespace, group, dataId, data string) {
		fmt.Println("config changed group:" + group + ", dataId:" + dataId + ", content:" + data)
	},
})

4.2 移除监听

//cancel config change
err = client.CancelListenConfig(vo.ConfigParam{
	DataId: "test.json",
	Group:  "tt",
})

4.3 发布配置

	_, err = client.PublishConfig(vo.ConfigParam{
		DataId:  "test-data",
		Group:   "test-group",
		Content: "hello world!",
	})
	if err != nil {
		fmt.Printf("PublishConfig err:%+v \n", err)
	}

4.4 删除配置

_, err = client.DeleteConfig(vo.ConfigParam{
	DataId:  "test-data",
	Group:   "test-group",
})

4.5 搜索配置

searchPage, _ := client.SearchConfig(vo.SearchConfigParam{
	Search:   "blur",
	DataId:   "", // 自定义
	Group:    "", // 自定义
	PageNo:   1,
	PageSize: 10,
})
fmt.Printf("Search config:%+v \n", searchPage) // 格式:&{TotalCount:0 PageNumber:1 PagesAvailable:0 PageItems:[]}

总结

  • 以上是官方提供的一些 example 的拆解,目前只是拿出来分析
  • 在真实使用的场合中,需要进行合适的封装来达到生产使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/646836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重学java 46.集合 ① Collection集合

事常与人违,事总在人为 —— 24.5.26 集合 知识导航 1.集合的特点以及作用 2.使用collection接口中的方法 3.使用迭代器迭代集合 4.ArrayList以及LinkedList的使用 5.使用增强for遍历集合 一、单列集合框架的介绍 1.长度可变的容器:集合 2.集合的特点 a.…

App推广新境界:Xinstall助你轻松突破运营痛点,实现用户快速增长!

在移动互联网时代,App已经成为企业营销不可或缺的一部分。然而,如何有效地推广App,吸引并留住用户,成为了众多企业面临的难题。今天,我们将为您揭秘一款神奇的App推广工具——Xinstall,它将助您轻松突破运营…

音视频开发8 音视频中SDL的使用,SDL 在windows上环境搭建,SDL 使用 以及 常用 API说明,show YUV and play PCM

1.SDL简介 SDL(Simple DirectMedia Layer),是一个跨平台的C语言多媒体开发库。 支持Windows、Mac OS X、Linux、iOS、Android 提供对音频、键盘、鼠标、游戏操纵杆、图形硬件的底层访问 很多的视频播放软件、模拟器、受欢迎的游戏都在使用…

我的前端封装之路

最近有粉丝提问了我一个面试中遇到的问题,他说面试的时候,面试官问我:你在以前的项目中封装过组件吗?或者做过npm公共库吗?遇到过什么问题吗?当时自己突然觉得好像没什么可回答的啊,但面试结束想…

【Torch学习笔记】

作者:zjk 和 的区别是逐元素相乘,是矩阵相乘 cat stack 的区别 cat stack 是用于沿新维度将多个张量堆叠在一起的函数。它要求所有输入张量具有相同的形状,并在指定的新维度上进行堆叠。

LabVIEW直方图应用解析

概述 在LabVIEW中,直方图是一种重要的工具,用于分析和展示数据的分布情况。它通过将数据分成若干区间并绘制对应频数,可以帮助用户了解数据的集中趋势、离散程度和分布形态。本文将详细介绍LabVIEW中直方图的使用方法、适用场合、实际意义及…

解决使用ServletUtil.write方法下载接口文件中文乱码问题

文章目录 前言代码片段如下:一、问题分析二、解决办法总结 前言 在开发过程中遇到的一个小问题,实现一个下载模板的接口,我选择了使用hutool包的ServletUtil.write方法去进行文件下载,但调试过程中下载出来的文件名是乱码的&#…

DEM、DSM和DTM之间的区别及5米高程数据获取

在日常的学习工作中我们经常会遇到DEM、DSM和DTM等术语,它们的含义类似,甚至相互替换。那么它们之间有什么区别?这里我们对这些术语进行介绍。 DEM(数字高程模型,Digital Elevation Model): 定义…

JavaFX安装与使用

前言 最近学习了javafx,开始时在配置环境和导包时遇到了一些麻烦,关于网上很多方法都尝试过了,现在问题都解决了,和大家分享一下我是怎么实现javafx的配置,希望大家可以通过这个方法实现自己的环境配置! 🙈个人主页: 心.c 🔥文章专题:javafx &#x1f49…

5月26号总结

目录 刷题记录(Codeforces Round 947 (Div. 1 Div. 2)前三题) 1.A. Bazoka and Mochas Array 2.B. 378QAQ and Mochas Array 3.C. Chamo and Mochas Array 刷题记录(Codeforces Round 947 (Div. 1 Div. 2)前三题) 1.A. Bazok…

【开源可视化报表设计器】借力实现高效率流程化办公!

进行数字化转型、实现流程化办公,这些应该是目前很多企业都想要实现的目标吧。那么,利用什么样的软件平台可以实现?低代码技术平台拥有可视化界面、灵活操作、好维护等众多优势特点,可以借助低代码技术平台、开源可视化报表设计器…

H5扫描二维码相关实现

H5 Web网页实现扫一扫识别解析二维码,就现在方法的npm包就能实现,在这个过程中使用过html5-qrcode 和 vue3-qr-reader。 1、html5-qrcode的使用 感觉html5-qrcode有点小坑,在使用的时候识别不成功还总是进入到错误回调中出现类似NotFoundExc…

用Prometheus全面监控MySQL服务:一篇文章搞定

简介 在现代应用中,MySQL数据库的性能和稳定性对业务至关重要。有效的监控可以帮助预防问题并优化性能。Prometheus作为一款强大的开源监控系统,结合Grafana的可视化能力,可以提供全面的MySQL监控方案。 设置Prometheus 安装Prometheus 使…

JVM学习-方法区(元空间)

运行时数据区结构图 从线程共享与否角度来看 栈、堆、方法区的交互关系 方法区 《Java虚拟机规范》中明确说明:“尽管所有的方法区在逻辑上属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩”,但对于HotSpotJVM而…

Qt 概述

Qt 背景介绍 什么是 Qt Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 。它为应⽤程序开发者提供了建⽴艺术级图形界⾯所需的所有功能。它是完全⾯向对象的,很容易扩展。Qt 为开发者提供了⼀种基于组件的开发模式,开发者可以通过简单的拖拽和组合来实…

绘唐3模型怎么放本地sd安装及模型放置位置 及云端sd部署

绘唐3模型怎么放本地sd安装及模型放置位置 及云端sd部署 资料里面授权方式: https://qvfbz6lhqnd.feishu.cn/wiki/CcaewIWnSiAFgokOwLycwi0Encf 云端和模型之间存在某种关联性。云端通常用于存储和管理大量数据,并提供计算和资源的服务。模型是对数据进…

Shell字符串变量

目标 能够使用字符串的3种方式 掌握Shell字符串拼接 掌握shell字符串截取的常用格式 能够定义Shell索引数组和关联数组 能够使用内置命令alias,echo,read,exit,declare操作 掌握Shell的运算符操作 Shell字符串变量 介绍 字符串(String)就是一系…

2024/05/25学习记录

1、面经复习:前端广度 2、代码随想录刷题:动态规划 3、rosebush 完成input组件基础

nacos 2.3.3 Windows系统安装详细版

1,下载 https://github.com/alibaba/nacos/releases 2,解压 3,将nacos的内置库(derby),修改为我们自己的 mysql 3.1 创建一个数据库 3.2 连接数据库 3.3 执行mysql 脚本,在nacos的conf 目录下 mysql-schema.sql 执…

ffpmeg windows WSl 编译so

1.NDK 环境变量配置 2.git clone ffpmeg 3.创建脚本(需先下载gcc编译器) 64位脚本如下 #!/bin/bashexport NDK/home/test/ndk20 #这里配置先你的 NDK 路径 TOOLCHAIN$NDK/toolchains/llvm/prebuilt/linux-x86_64function build_android {./configure \ …