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文件

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

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.观察者设计的广泛应用;

结束

欢迎大家点点关注,点点赞,感谢!

Nacos使用和注册部分源码介绍的更多相关文章

  1. GGTalk——C#开源即时通讯系统源码介绍系列(一)

    坦白讲,我们公司其实没啥技术实力,之所以还能不断接到各种项目,全凭我们老板神通广大!要知道他每次的饭局上可都是些什么人物! 但是项目接下一大把,就凭咱哥儿几个的水平,想要独立自主.保质保量保期地一个个 ...

  2. 4- vue django restful framework 打造生鲜超市 -restful api 与前端源码介绍

    4- vue django restful framework 打造生鲜超市 -restful api 与前端源码介绍 天涯明月笙 关注 2018.02.20 19:23* 字数 762 阅读 135 ...

  3. C++、VC++、MFC网页自动注册、登陆、发帖、留言,QQ注册、QQ申请器源码、注册邮箱源码、自动发帖源码

    C++.VC++.MFC网页自动注册.登陆.发帖.留言,QQ注册.QQ申请器源码.注册邮箱源码.自动发帖源码   参考资料: 自动登录yahoo邮箱http://blog.csdn.net/suisu ...

  4. Crackme006 - 全新160个CrackMe学习系列(图文|视频|注册机源码)

    知乎:逆向驿站 原文链接 CrackMe006 | 难度适中适合练手 |160个CrackMe深度解析(图文+视频+注册机源码) crackme006,依然是delphi的,而且没壳子,条线比较清晰, ...

  5. 1-开发共享版APP(源码介绍)-BUG修复

    这一系列文章将介绍APP的源码,这一节作为所有BUG问题修复! https://www.cnblogs.com/yangfengwu/category/1512162.html    //开发共享版A ...

  6. 生成MyEclipse6.5&7.5&8.5 注册机源码

    分类: java技术2010-09-30 21:46 26638人阅读 评论(6) 收藏 举报 myeclipsejavastringimportinputbyte 生成MyEclipse8.5注册码 ...

  7. Java中常用的七个阻塞队列第二篇DelayQueue源码介绍

    Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...

  8. Sentinel Dashboard(基于1.8.1)流控规则持久化到Nacos——涉及部分Sentinel Dashboard源码改造

    前言 之前虽然也一直在使用sentinel实现限流熔断功能,但却没有好好整理之前看的源码与资料,今天有时间将之前自己整理过的资料写成一篇博文,或者是是一篇关于Sentinel(基于目前最近版本1.8, ...

  9. HoverTree系统源码介绍

    HoverTree是一个开源asp.net系统.系统的效果请到:http://hovertree.com体验. 源码描述:一.源码特点采用典型的三层架构进行开发,实现了留言板的功能,后台管理,留言审核 ...

随机推荐

  1. proxySQL with MGR

    环境信息 hostname IP port role comm ms81 192.168.188.81 3399 master ms82 192.168.188.82 3399 slave ms83 ...

  2. mysql批量刷新用户密码

    不知道用户密码,并且不改变用户密码的情况下,批量刷新MySQL数据库用户的密码 select concat('alter user \'',user,'\'@\'',host,'\' identifi ...

  3. jmeter__编写脚本学习笔记、备忘

    web持续添加 前言: 1. token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件:也叫关联 2. cookie就是写在客户端的一个txt文件,里面包括你登录信息之 ...

  4. 详解汇编语言B和LDR指令与相对跳转和绝对跳转的关系

    @ 目录 为什么要有相对跳转和绝对跳转? 在程序中只有相对跳转/绝对跳转是否可以? B(BL)和LDR指令具体怎么执行的? B(BL)和LDR跳转范围是如何规定的? 为什么要有相对跳转和绝对跳转? 顺 ...

  5. HBase删除数据

    hbase官方文档中描述了,hbase删除数据可以总结为下面三种(Java API有很多接口,可以总结下面的几种): 删除一个列的指定版本 删除一个列的所用版本 删除指定列族的所有列 hbase删除数 ...

  6. js上 十二、函数初步-1

    11-1.引入(认识函数) ​ 引入: 说起函数,其实我们并不陌生,在初中数学中我们就接触过函数:例如我们所学的 y = 2X+1 ; 这是一个二元一次方程,也是我们数字中的函数: ​ 当我们每次输入 ...

  7. HDU4388-Stone Game II-Nim变形

    http://acm.hdu.edu.cn/showproblem.php?pid=4388 Nim变形,对一个\(n\)个石子的堆,每次取\(k(0<k<n)\)个(注意不能全取光),同 ...

  8. Python高级语法-对象实例对象属性-Property总结(4.6.2)

    @ 目录 1.说明 2.代码 关于作者 1.说明 property属性,返回的是值 不是callable的,也就是不能使用方法来调用 只能传入self,不能传入其他 用处,能返回局部数据,比如当分页的 ...

  9. ASP.NET Web API运行提示:找到了与该请求匹配的多个操作的解决方法

  10. C#中RDLC报表中日期显示格式

    转换为日期类型再格式化 =CDate(Fields!UseDate.Value).ToString("yyyy-MM-dd") 使用Format ==Format(Fields!C ...