Nacos使用和注册部分源码介绍

news/2024/12/23 20:06:42/

Nacos简单介绍

Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
接下来主要介绍Nacos作为注册中心的使用和注册部分的源码解析。

Nacos安装

Nacos预装环境

Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境这里就不介绍Maven和Java安装,大家自行安装一下。

安装的方式主要有两种:
  1. 从GitHub上下载源码安装:
//下载源码的地址
git clone https://github.com/alibaba/nacos.git
cd nacos/
//编译源码
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U  
ls -al distribution/target/
//进入编译包
cd distribution/target/nacos-server-$version/nacos/bin

2.下载安装包的形式:

tar -xvf nacos-server-$version.tar.gz
cd nacos/bin
启动服务器

启动命令(standalone代表着单机模式运行,非集群模式):

sh startup.sh -m standalone
关闭服务器
sh shutdown.sh
单机环境下使用Mysql:

在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力,具体的操作步骤:

  1. 安装数据库,版本要求:5.6.5+
  2. 初始化mysql数据库,数据库初始化文件:nacos-mysql.sql
  3. 修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

对于单机来说我们就是玩个demo是够的,但是对于生产来说我们就要考虑高可用的方案了:
对于集群部署的方式如果在虚拟机环境就采用Nagix负载3台虚拟机,对于K8S的环境通过Service负载3台Pod的形式搭建高可用环境,对于数据库选择来说最好采用主从结构,保证数据库的高可用。
整体的部署可能如下;


下图就是搭建好以后的整体界面:

Nacos使用

1.创建一个Spring Boot空应用

2.编辑pom.xml文件

    <properties><springboot.vetsion>2.2.11.RELEASE</springboot.vetsion><spring-cloud-version>Hoxton.SR9</spring-cloud-version><spring-cloud-alibaba-version>2.2.3.RELEASE</spring-cloud-alibaba-version></properties>
<dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${springboot.vetsion}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud-version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba-version}</version><type>pom</type><scope>import</scope></dependency>     </dependencies>
</dependencyManagement>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>

3.创建应用的启动项目

@SpringBootApplication(scanBasePackages = {"com.springcloud.study"})
@EnableDiscoveryClient
public class SystemApplication {public static void main(String[] args) {SpringApplication.run(SystemApplication.class, args);}
}

4.配置application.yaml文

server:port: 8081
spring:application:name: system# 数据源配置项datasource:url: jdbc:mysql://127.0.0.1:3306/study_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123456#nacos基础配置cloud:nacos:discovery:server-addr: 10.226.73.115:8886#环境选择#namespace: b7d341fc-df29-45ce-b3cd-4415f66b1ee0

5.启动项目

Nacos注册部分源码分析

客户端通过Rest接口式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。 Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。对于注册部分的源码整体上分为两部分:

客户端注册源码

按照Spring Boot Starter的习惯,我们首先找到spring-cloud-starter-alibaba-nacos-discovery启动项,如下图所示:


标红部分的NacosServiceRegistryAutoConfiguration是我们注册部分关注的类,首先我们看下该类的整体的继承结构:
 


重点关注AbstractAutoServiceRegistration接口,NacosAutoServiceRegistration该Bean的注入就是我们注入开始的:
 


整体看下该类,基本上是对AbstractAutoServiceRegistration继承和实现,该类位于spring-cloud-common这个jar下面,Spring Cloud Commons模块是为了对微服务中的服务注册与发现、负载均衡、熔断器等功能提供一个抽象层代码,这个抽象层与具体的实现无关。这样这些功能具体的实现上可以采用不同的技术去实现,并可以做到在使用时灵活的更换。
NacosAutoServiceRegistration内部存在一个@EventListener注解,@EventListener是一种事件驱动编程在spring4.2的时候开始有的,可以理解为ApplicationListener接口的扩展,方便我们使用,可以理解为Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式;为的就是业务系统逻辑的解耦,提高可扩展性以及可维护性。事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已。
 


接下来我们重点看下AbstractAutoServiceRegistration内部start方法,
 


register的具体的实现类是NacosServiceRegistry,内部调用NacosNamingService的registerInstance方法,该方法内部通过调用NamingProxy的reqApi,通过NacosRestTemplate请求服务端的/instance方法注册到服务端。
 


 


至此完成了客户端注册到服务端,下图是整体的时序图:

服务端注册部分

服务端注册相对比较复杂一点,这块需要将Nacos源码下载一下,找到naming模块,InstanceController就是我们调用服务端的接口,如下图所示:


接下来重点看下ServiceManager的registerInstance的方法,如下图:
 


首先看下createEmptyService方法,该方法目的双肩一个双层的Map对象,用于存储注册应用的信息,整体的结构Map(namespace, Map(group::serviceName, Service)),这里正好对应注册中心介绍时候的张图,我们整体在看一下:
 


 


初始化的注册表结构以后,接下来就是将应用的信息注册添加到注册表中,主要分为两步如下图:
 


addIpAddresses就是获取当前注册服务的所有ip,整体的流程如下图:
 


这里的主要的重点是put方法,这里我们全部按照CP的场景去解释,AP的场景在未来的章节补充,CP的实现类是DistroConsistencyServiceImpl,如下图:
 


通过把需要注册到注册表的服务添加到阻塞队列当中,Notifier本质上一个线程,然后通过执行run内部的hander方法,如下图:
 


通过调用Service的onChange方法来变更注册表的信息,内部主要通过updateIPs完成注册表信息的表更,主要也是采用CopyOnWrite的思想,如下图:
 


到此服务端的注入就完成了,这个里面整体上有三处亮点:
1.CopyOnWrite的思想的广泛应用;
2.通过阻塞队列实现异步任务提升系统性能,并且解决并发写入问题;
3.观察者设计的广泛应用;
 


http://www.ppmy.cn/news/1106053.html

相关文章

嵌入式Linux驱动开发(同步与互斥专题)(二)

一、自旋锁spinlock的实现 自旋锁&#xff0c;顾名思义&#xff1a;自己在原地打转&#xff0c;等待资源可用&#xff0c;一旦可用就上锁霸占它。 ① 原地打转的是CPU x&#xff0c;以后CPU y会解锁&#xff1a;这涉及多个CPU&#xff0c;适用于SMP系统&#xff1b; ② 对于单…

直播|DITA内容发布工具解析 - 问答总结

9月6日&#xff0c;我们进行了一场名为“DITA内容发布工具解析”的直播。通过直播&#xff0c;大家了解到&#xff1a; DITA-OT简介 默认输出效果 定制以后输出效果 发布过程与样式定制 在问答环节&#xff0c;大家进行了热烈沟通。我将几个大家关心的问题和答复总结如下&…

学习 [Spring MVC] 的JSR 303和拦截器,提高开发效率

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《推荐】Spring与Mybatis集成整合》 ⛺️ 生活的理想&#xff0c;不断更新自己 ! 1.JSR303 1.1JSR303是什么 JSR 303是Java规范请求&#xff08;Java Specification Request&#xff09;…

【图解RabbitMQ-7】图解RabbitMQ五种队列模型(简单模型、工作模型、发布订阅模型、路由模型、主题模型)及代码实现

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…

STM32-HAL库07-软件SPI驱动0.96寸OLED

STM32-HAL库07-软件SPI驱动0.96寸OLED 一、所用材料&#xff1a; STM32VGT6自制控制板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 二、所学内容&#xff1a; 通过HAL库配置四个GPIO输出口&#xff0c;对其进行软件模拟SPI发送规则&#xff0c;进而驱动OLED进行数…

目标检测YOLO实战应用案例100讲-基于深度学习的可见光遥感图像目标检测

目录 前言 遥感图像目标的特点 基于深度学习的目标检测技术 2.1引言 2.2卷积神经网络

每天几道Java面试题(第三天)

目录 第三幕、第一场&#xff09;面试中第二场&#xff09;第三场&#xff09; 友情提醒 背面试题很枯燥&#xff0c;加入一些戏剧场景故事人物来加深记忆。PS:点击文章目录可直接跳转到文章指定位置。 第三幕、 第一场&#xff09;面试中 【面试官老吉&#xff0c;面试官潘…

【Linux】ubuntu 添加新硬盘进行分区

ubuntu添加新硬盘&#xff0c;进行分区&#xff0c;并挂载到/home目录。 01 查看已有的磁盘&#xff0c;可以看到sdb还没有分区。 sudo fdisk -l 可以看到各个硬盘的设备名&#xff0c;一般以sda、sdb、sdc命名&#xff0c;下面以/dev/sdb为例&#xff0c; 02 进入sdb进行分区…