当前位置: 首页 > news >正文

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:latestcontainer_name: nacos-standaloneenv_file:- ./config.envvolumes:- ./standalone-logs/:/home/nacos/logsports:- "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 mainimport ("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 ServerConfigsc := []constant.ServerConfig{*constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")),}//create ClientConfigcc := *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 clientclient, err := clients.NewNamingClient(vo.NacosClientParam{ClientConfig:  &cc,ServerConfigs: sc,},)if err != nil {panic(err)}// RegisterregisterServiceInstance(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, clustersgetService(client, vo.GetServiceParam{ServiceName: "demo.go",GroupName:   "tt",// Clusters:    []string{"cluster-a"},})//wait for client pull change from servertime.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_GROUPgetAllService(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 ipPort:        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 mainimport ("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 ServerConfigsc := []constant.ServerConfig{*constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")),}//create ClientConfigcc := *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 clientclient, err := clients.NewConfigClient(vo.NacosClientParam{ClientConfig:  &cc,ServerConfigs: sc,},)if err != nil {panic(err)}//get configcontent, 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 的拆解,目前只是拿出来分析
  • 在真实使用的场合中,需要进行合适的封装来达到生产使用

相关文章:

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

Nacos 概述 文档:https://nacos.io/docs/latest/what-is-nacos/搭建:https://nacos.io/docs/latest/quickstart/quick-start-docker/有很多种搭建方式,我们这里使用 docker 来搭建 Nacos 的搭建 这里,我们选择单机模式&#xf…...

基于Hadoop的城市公共交通大数据时空分析

基于Hadoop的城市公共交通大数据时空分析 “Spatio-temporal Analysis of Urban Public Transportation Big Data based on Hadoop” 完整下载链接:基于Hadoop的城市公共交通大数据时空分析 文章目录 基于Hadoop的城市公共交通大数据时空分析摘要第一章 引言1.1 研究背景1.2 …...

DNS服务的部署与配置(2)

1、dns的安装及开启 dnf install bind.x86_64 -y #安装 #Berkeley Internet Name Domain (BIND) systemctl enable --now named #启用dns服务,服务名称叫named firewall-cmd --permanent --add-servicedns #火墙设置 firewall-cmd --reload …...

MySql--SQL语言

目录 SQl---DDL 结构定义 创建、删除 数据库 代码 运行 设计表 数据类型 整数 浮点数 主键 约束 主键自增长 默认值 字段注释 创建、删除 表 代码 运行 代码 代码 运行 SQL---DML 数据操纵 插入数据 代码 运行 代码 运行 代码 运行 代码 …...

【网络安全】2030年十大新兴网络安全威胁

欧盟网络安全局(ENISA)已发布了一份全面的清单,列出了预计到2030年将影响数字领域的十大新兴网络安全威胁。 该预测是为期八个月的广泛研究的成果,融合了ENISA前瞻专家小组、CSIRTs网络以及欧盟CyCLONe专家的见解。 这项研究突显…...

python数据分析-CO2排放分析

导入所需要的package import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import datetime %matplotlib inline plt.rcParams[font.sans-serif] [KaiTi] #中文 plt.rcParams[axes.unicode_minus] False #负号 数据清洗…...

2024宝藏工具EasyRecovery数据恢复软件免费版本下载

在这个数字化的时代,数据已经成为我们生活中的重中之重。无论是工作中的重要文件,还是手机中珍贵的照片,我们都依赖着这些数据。然而,数据丢失的情况时有发生,可能是误删,可能是设备故障,更可能…...

【EventSource错误解决方案】设置Proxy后SSE发送的数据只在最后接收到一次,并且数据被合并

【EventSource错误解决方案】设置Proxy后SSE发送的数据只在最后接收到一次,并且数据被合并 出错描述 出错原因与解决方案 出错描述 SSE前后端一切正常,但是fetchEventSource 的onmessage回调函数只在所有流都发送完毕后,才会执行一次。 前…...

如何在linux命令行(终端)执行ipynb 文件。可以不依赖jupyter

1.安装 runipy pip install runipy 2.终端运行 runipy <YourNotebookName>.ipynb 在终端命令行执行shell脚本&#xff0c;&#xff08;也可以在crontab 中执行&#xff09;&#xff1a; (base) [recommendapp-0-5-B-006 script]$ cat run1.sh #!/bin/bashcd /home/recom…...

基于YOLOv8的车牌检测与识别(CCPD2020数据集)

前言 本篇博客主要记录在autodl服务器中基于yolov8实现车牌检测与识别&#xff0c;以下记录实现全过程~ yolov8源码&#xff1a;GitHub - ultralytics/ultralytics: NEW - YOLOv8 &#x1f680; in PyTorch > ONNX > OpenVINO > CoreML > TFLite 一、环境配置 …...

驱动开发之新字符设备驱动开发

1.前言 register_chrdev 和 unregister_chrdev 这两个函数是老版本驱动使用的函数&#xff0c;现在新的 字符设备驱动已经不再使用这两个函数&#xff0c;而是使用 Linux 内核推荐的新字符设备驱动 API 函数。 旧版本的接口使用&#xff0c;感兴趣可以看下面这个博客&#…...

【JMU】21编译原理期末笔记

本拖延症晚期患者不知不觉已经有半年没写博客了&#xff0c;天天不知道在忙什么。 乘着期末周前赶紧先把编译原理上传了&#xff0c;我记得我这科是86分&#xff0c;有点小遗憾没上90&#xff0c;但是总体不错。 链接&#xff1a;https://pan.baidu.com/s/1gO8pT7paHv1lkM_ZpkI…...

就业信息|基于SprinBoot+vue的就业信息管理系统(源码+数据库+文档)

就业信息管理系统 目录 基于SprinBootvue的就业信息管理系统 一、前言 二、系统设计 三、系统功能设计 1前台功能模块 2后台功能模块 4.2.1管理员功能 4.2.2学生功能 4.2.3企业功能 4.2.4导师功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设…...

一.架构设计

架构采用 ddd 架构&#xff0c;不同于传统简单的三层的架构&#xff0c;其分层的思想对于大家日后都是很有好处的&#xff0c;会给大家的思想层级&#xff0c;提高很多。 传统的项目 现有的架构 采取ddd架构&#xff0c;给大家在复杂基础上简化保留精髓&#xff0c;一步步进行…...

<学习笔记>从零开始自学Python-之-实用库篇(一)-pyscript

由Anaconda创建的PyScript是一项实验性的但很有前途的新技术&#xff0c;它使python运转时在支撑WebAssembly的浏览器中作为一种脚本言语运用。 每个现代常用的浏览器现在都支撑WebAssembly&#xff0c;这是许多言语&#xff08;如C、C和Rust&#xff09;能够编译的高速运转时…...

Vue项目中npm run build 卡住不执行的几种情况(实战版)

方法一 一&#xff1a;比较常见是镜像导致的原因 我们可以找到build/check-versions文件 将这段代码注释,重新运行就可以解决这个问题 if (shell.which(npm)) {versionRequirements.push({name: npm,currentVersion: exec(npm --version),versionRequirement: packageConfig.en…...

《Python源码剖析》之pyc文件

前言 前面我们主要围绕pyObject和pyTypeObject聊完了python的内建对象部分&#xff0c;现在我们将开启新的篇章—python虚拟机&#xff0c;将聚焦在python的执行部分&#xff0c;搞懂从“代码”到“执行”的过程。开启新的篇章之前&#xff0c;你也许会有一个疑惑&#xff1a;我…...

Python零基础-中【详细】

接上篇继续&#xff1a; Python零基础-上【详细】-CSDN博客 目录 十、函数式编程 1、匿名函数lambda表达式 &#xff08;1&#xff09;匿名函数理解 &#xff08;2&#xff09;lambda表达式的基本格式 &#xff08;3&#xff09;lambda表达式的使用场景 &#xff08;4&…...

回溯 leetcode

22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()","()(())"…...

Android firebase消息推送集成 FCM消息处理

FirebaseMessagingService 是 Firebase Cloud Messaging (FCM) 提供的一个服务&#xff0c;用于处理来自 Firebase 服务器的消息。它有几个关键的方法&#xff0c;你提到的 onMessageReceived、doRemoteMessage 和 handleIntent 各有不同的用途。下面逐一解释这些方法的作用和用…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...