SpringCloudAlibaba:Nacos实现原理详解

article/2025/9/18 16:24:53

欢迎关注方志朋的博客,回复”666“获面试宝典

Nacos 架构

e25c3fb447449c7bed76e7cfed895adb.png

Provider APP:服务提供者

Consumer APP:服务消费者

Name Server:通过VIP(Virtual IP)或DNS的方式实现Nacos高可用集群的服务路由

Nacos Server:Nacos服务提供者,里面包含的Open API是功能访问入口,Conig Service、Naming Service 是Nacos提供的配置服务、命名服务模块。

Consitency Protocol是一致性协议,用来实现Nacos集群节点的数据同步,这里使用的是Raft算法(Etcd、Redis哨兵选举)

Nacos Console:控制台

注册中心的原理

  • 服务实例在启动时注册到服务注册表,并在关闭时注销

  • 服务消费者查询服务注册表,获得可用实例

  • 服务注册中心需要调用服务实例的健康检查API来验证它是否能够处理请求

bf32fa95196b29df45c07d7c89675486.png

Spring Cloud 完成注册的时机

在Spring-Cloud-Common包中有一个类org.springframework.cloud. client.serviceregistry .ServiceRegistry ,它是Spring Cloud提供的服务注册的标准。集成到Spring Cloud中实现服务注册的组件,都会实现该接口。

cf25a0e690c79c14ae4e04b15b01623a.png

该接口有一个实现类是NacoServiceRegistry

 Spring Cloud集成Nacos的实现过程:

在spring-clou-commons包的META-INF/spring.factories中包含自动装配的配置信息如下:

8503d98d42212d94e0d369b62fca270b.png

其中AutoServiceRegistrationAutoConfiguration就是服务注册相关的配置类:

c3a10e23f7beb8e2ae0fceec60094d9f.png

在AutoServiceRegistrationAutoConfiguration配置类中,可以看到注入了一个AutoServiceRegistration实例,该类的关系图如下所示。

f9c779b6756dfdcc79597f0c7af455c5.png

可以看出, AbstractAutoServiceRegistration抽象类实现了该接口,并且最重要的是NacosAutoServiceRegistration继承了AbstractAutoServiceRegistration。

看到EventListener我们就应该知道,Nacos是通过Spring的事件机制继承到SpringCloud中去的。

AbstractAutoServiceRegistration实现了onApplicationEvent抽象方法,并且监听WebServerInitializedEvent事件(当Webserver初始化完成之后) , 调用this.bind ( event )方法。

26d2667322a9c5928bed745c1d8ea83f.png

最终会调用NacosServiceREgistry.register()方法进行服务注册。

a1541ec8f7ea9393f672d3ea269ead39.png

0121dd6f8da7475b41f028594c6f7cff.png

NacosServiceRegistry的实现

在NacosServiceRegistry.registry方法中,调用了Nacos Client SDK中的namingService.registerInstance完成服务的注册。

08b9819f89751d02fb0bd66608b7248c.png

跟踪 NacosNamingService的registerInstance()方法:

f12076d8a0197a756d6dd77faf9388c6.png

通过beatReactor.addBeatInfo()创建心跳信息实现健康检测, Nacos Server必须要确保注册的服务实例是健康的,而心跳检测就是服务健康检测的手段。

serverProxy.registerService()实现服务注册

心跳机制:

00272ff8272bc155d28926410c26ccc8.png

从上述代码看,所谓心跳机制就是客户端通过schedule定时向服务端发送一个数据包 ,然后启动-个线程不断检测服务端的回应,如果在设定时间内没有收到服务端的回应,则认为服务器出现了故障。Nacos服务端会根据客户端的心跳包不断更新服务的状态。

注册原理:

Nacos提供了SDK和Open API两种形式来实现服务注册。

Open API:

359f91f07438f125774dca3670552845.png

SDK:

d9cecf2097d7df87bfa42d16f8a57764.png

这两种形式本质都一样,底层都是基于HTTP协议完成请求的。所以注册服务就是发送一个HTTP请求:

a4151514d91fbcd87f017e26c1e2ea08.png

对于nacos服务端,对外提供的服务接口请求地址为nacos/v1/ns/instance,实现代码咋nacos-naming模块下的InstanceController类中:

5e4e86cacd44c92d923f2a4cd2e39bf1.png

  • 从请求参数汇总获得serviceName(服务名)和namespaceId(命名空间Id)

  • 调用registerInstance注册实例

5ec1b3540ff4dc05d26ce3111bbe7bdd.png

  • 创建一个控服务(在Nacos控制台“服务列表”中展示的服务信息),实际上是初始化一个serviceMap,它是一个ConcurrentHashMap集合

  • getService,从serviceMap中根据namespaceId和serviceName得到一个服务对象

  • 调用addInstance添加服务实例

0f341737b7397fc4974588c038a68b08.png

7522c56a1034e0089f5c6afe757715a6.png

  • 根据namespaceId、serviceName从缓存中获取Service实例

  • 如果Service实例为空,则创建并保存到缓存中

b5459c14b5c1363b3607bc66a5d5515a.png

  • 通过putService()方法将服务缓存到内存

  • service.init()建立心跳机制

  • consistencyService.listen实现数据一致性监听

service.init ( ) 方法的如下图所示,它主要通过定时任务不断检测当前服务下所有实例最后发送心跳包的时间。如果超时,则设置healthy为false表示服务不健康,并且发送服务变更事件。在这里请大家思考一一个问题,服务实例的最后心跳包更新时间是谁来触发的?实际上前面有讲到, Nacos客户端注册服务的同时也建立了心跳机制。

6389d6ee421cd0c96d7e720b613507e1.png

putService方法,它的功能是将Service保存到serviceMap中:

ace57611f7bd4977fe951d9c49af2abd.png

继续调用addInstance方法把当前注册的服务实例保存到Service中:

4749c97af15bce20887acb7e0d3029bb.png

总结:Nacos客户端通过Open API的形式发送服务注册请求,Nacos服务端收到请求后,做以下三件事:

1. 构建一个Service对象保存到ConcurrentHashMap集合中

2. 使用定时任务对当前服务下的所有实例建立心跳检测机制

3. 基于数据一致性协议服务数据进行同步

服务提供者地址查询

Open API:

288ee58efe96ed583e6e5456642788f2.png

SDK:

d38d18ff3d0ad0eb8bbdd9259f5480c0.png

InstanceController中的list方法:

854cf261928ab8ab8c8aa3d3f6a9cd45.png

  • 解析请求参数

  • 通过doSrvIPXT返回服务列表数据

17190c69c5d0a384ceb34c3966d2410e.png

309697c9461828d8d814d82b1e483404.png

  • 根据namespaceId、serviceName获得Service实例

  • 从Service实例中基于srvIPs得到所有服务提供者实例

  • 遍历组装JSON字符串并返回

Nacos服务地址动态感知原理

可以通过subscribe方法来实现监听,其中serviceName表示服务名、EventListener表示监听到的事件:

f796ef5a5df8a32b87ce57cb5c3803e7.png

具体调用方式如下:

e07c2b14298fdd11c6e50625ae880abd.png

或者调用selectInstance方法,如果将subscribe属性设置为true,会自动注册监听:

57c0feee920e1856c37a5b72f10cdd59.png

2911f21ca731c369a2ec0d8d1c8db5c7.png

Nacos客户端中有一个HostReactor类,它的功能是实现服务的动态更新,基本原理是:

客户端发起时间订阅后,在HostReactor中有一个UpdateTask线程,每10s发送一次Pull请求,获得服务端最新的地址列表

对于服务端,它和服务提供者的实例之间维持了心跳检测,一旦服务提供者出现异常,则会发送一个Push消息给Nacos客户端,也就是服务端消费者

服务消费者收到请求之后,使用HostReactor中提供的processServiceJSON解析消息,并更新本地服务地址列表。

地址:https://blog.csdn.net/cold___play/article/details/108032204
热门内容:
  • 面试官:有了 for 循环 为什么还要 forEach ?

  • 网传铁饭碗职业排名,公务员仅排第八!

  • 为什么 Java 中“1000==1000”为false,而”100==100“为true?

  • 别再写 main 方法测试了,太 Low!这才是专业 Java 测试方法!

  • 新来的同事问我 where 1=1 是什么意思

3b1932ce688a425ec66e2c0a29ebfad1.png

 
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡


http://chatgpt.dhexx.cn/article/pUHBLcww.shtml

相关文章

Spring Boot入门

1.什么是Spring Boot Spring 诞生时是 Java 企业版的轻量级代替品。通过依赖注入和面向切面编程,用简单的Java 对象实现了 EJB 的功能。 虽然 Spring 的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring 用 XML 配置,而…

Java NIO?看这一篇就够了!

点击上方“方志朋”,选择“置顶或者星标” 你的关注意义重大! ✎前言 现在使用NIO的场景越来越多,很多网上的技术框架或多或少的使用NIO技术,譬如Tomcat,Jetty。学习和掌握NIO技术已经不是一个JAVA攻城狮的加分技能&am…

今日头条技术架构分析

点击上方“方志朋”,选择“设为星标” 回复”666“获取新整理的面试资料 来源:blog.csdn.net/mucaoyx/article/details/84498468 一、产品背景1、文章抓取与分析2、用户建模3、新用户的“冷启动”4、推荐系统5、数据存储6、消息推送 二、今日头条系统架构…

写了 5 年 Java,这些坑还是没躲过……

我常常在想,一个人具备怎样的素质和能力,才称得上高级工程师?估计有不少人会说,“基础过硬、熟练掌握一门编程语言、至少看过一个优秀开源项目的源代码、有过高并发工作经验、沟通能力强”。 上面这些都很对,这些也都是…

专访方志朋:2018年仍然是微服务飞速发展的一年

方志朋,毕业于武汉理工大学硕士学位。 CSDN博客专家、Spring Cloud中国社区联合创始人。 《深入理解Spring Cloud与微服务构建》作者。 Spring Cloud作为Java语言的微服务落地框架,在Spring开源社区和Pivatol、Netflix两大公司的推动下飞速发展&#xf…

顶配版阿里大佬面试笔记+300道硬核面试题,跪着啃完了。。。。

金九银十刚过去,有一部分朋友在这期间肯定经历了一番大厂面试的洗礼,不知道大家是经受住了考验如愿以偿了,还是折戟沉沙无功而返呢? 身边已经有技术大佬顺利通过了阿里P6/P7的面试,在30岁之前成功跳槽进大厂&#xff1…

我是一个线程池

点击上方蓝色“方志朋”,选择“设为星标” 回复“666”获取独家整理的学习资料! 线程池的自我介绍 我是一个线程池(ThreadPoolExecutor),我的主要工作是管理在我这的多个线程(Thread)&#xff0…

好用到爆的 Java 技巧

点击上方“方志朋”,选择“设为星标” 回复”666“获取新整理的面试文章 来自:Lrwin的技术博客链接:http://lrwinx.github.io/2017/03/04/细思极恐-你真的会写java吗/ 本文不是一个吹嘘的文章,不会讲很多高深的架构,相…

Spring Cloud和Spring Boot高级视频

内容是之前发过的,大家说找不到,重新发一次 spring cloud 视频内容: spring boot 视频内容: 下载方式: 微信公众平台回复“C”免费获取springcloud,回复“B"免费获取springboot 4000G java高级架构师进阶 视频下载…

华为最美小姐姐,被外派墨西哥后...

欢迎关注方志朋的博客,回复”666“获面试宝典 来源丨《华为人》、心声社区 作者丨潘昱 2018年,坐在UCLA大学教室里,我和华为进行了一场视频面试。去投行从事对冲基金业务,还是去四大会计师事务所做一名税务咨询师?当时…

Java 和 C 长期霸权结束

欢迎关注方志朋的博客,回复”666“获面试宝典 TIOBE 公布了 2021 年 10 月的编程语言排行榜。 在进行了几个月的追逐之后,Python 成功在 10 月份超越了霸榜已久的 C 语言,夺得了 TIOBE 编程语言排行榜首的位置。TIOBE CEO Paul Jansen 评价称…

Spring Cloud之路---1.注册中心eureka与服务提供者

根据方志鹏大神的观点而来,他的博客地址: http://blog.csdn.net/forezp/article/details/70148833 简介:Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路…

SpringBoot 生产中 16 条最佳实践

欢迎关注方志朋的博客,回复”666“获面试宝典 Spring Boot是最流行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践。这些内容是基于我的个人经验和一些熟知的Spring Boot专家的文章。 在…

SpringBoot快速开发利器:CLI 属实真牛逼!

欢迎关注方志朋的博客,回复”666“获面试宝典 来源:blog.csdn.net/qq_31635851/article/details/120411711/ 安装 Spring Boot CLI演示项目结构用 Spring Boot CLI 创建 Hello World 示例使用 Grab 注释Spring Boot CLI 测试应用程序使用 Spring Boot CL…

一个程序员的水平能差到什么程度?

欢迎关注方志朋的博客,回复”666“获面试宝典 来源:www.zhihu.com/question/314644210 逛知乎的时候,看到一个有意思的话题:一个程序员的水平能差到什么程度? 看了下面的回答,不得不说,真是小刀…

spring boot面试问题集锦

方志鹏 2019/09/06 Q: 什么是spring boot? A:多年来,随着新功能的增加,spring变得越来越复杂。只需访问页面https://spring.io/projects,我们将看到所有在应用程序中使用的不同功能的spring项目。如果必须启动一个新…

五分钟体验分布式事务框架Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。本教程旨在为读者提供一个快速入门seata的案例,详细使用请参考…

SpringBoot非官方教程 | 第二十五篇:2小时学会springboot

转载请标明出处: https://www.fangzhipeng.com/springboot/2017/05/25/sb25-2hour.html 本文出自方志朋的博客 一.什么是spring boot Takes an opinionated view of building production-ready Spring applications. Spring Boot favors convention over configurat…

Spring Cloud Alibaba教程:使用Nacos作为配置中心

转载请标明出处: https://blog.csdn.net/forezp/article/details/90729945 本文出自方志朋的博客 个人博客纯净版https://www.fangzhipeng.com/springcloud/2019/06/01/sc-nacos-config.html 在上一篇文章中讲解了如何使用Nacos作为服务注册中心注册。Nacos除了可以…

20 个实例玩转 Java 8 Stream

点击关注公众号,Java干货及时送达 先贴上几个案例,水平高超的同学可以挑战一下: 1. 从员工集合中筛选出salary大于8000的员工,并放置到新的集合里。 2. 统计员工的最高薪资、平均薪资、薪资之和。 3. 将员工按薪资从高到低排序&am…