【深入理解SpringCloud微服务】深入理解nacos

【深入理解SpringCloud微服务】深入理解nacos

  • Nacos服务注册
  • 内存注册表
  • 内存注册表的更新
  • 通知客户端服务变更、服务同步、健康检查
  • 2.x版本nacos的变化

Nacos服务注册

spring-cloud-alibaba-nacos-discovery通过实现spring-cloud-commons规范定义的接口,完成nacos接入spring-cloud后的客户端自动注册,我们不研究Nacos如何实现spring-cloud-commons规范,只要知道最终是利用Spring的事件监听机制触发服务注册

在这里插入图片描述

然后就会调用nacos的NamingService进行服务注册,所以真正的入口是这个NamingService

nacos总体上也是CS结构:
在这里插入图片描述

有一个nacos服务端接收http请求,然后我们的微服务集成了一个nacos客户端,发送http请求给nacos服务端,这个nacos客户端就是NamingService。通过Spring的事件监听机制触发NamingService的调用,而NamingService通过HttpURLConnection发送http请求。

在这里插入图片描述

AbstractAutoServiceRegistration#onApplicationEvent:

    public void onApplicationEvent(WebServerInitializedEvent event) {this.bind(event);}public void bind(WebServerInitializedEvent event) {...this.start();...}public void start() {...this.register();...}protected void register() {this.serviceRegistry.register(this.getRegistration());}

上面的this.serviceRegistry就是NacosServiceRegistry,this.getRegistration()返回的就是NacosRegistration,然后this.serviceRegistry.register(this.getRegistration())就会进入NacosServiceRegistry的register方法。

NacosServiceRegistry#register

	@Overridepublic void register(Registration registration) {...namingService.registerInstance(serviceId, group, instance);...}

调用NamingService的registerInstance方法进行服务注册,里面就是向nacos服务端发起服务注册的http请求了。

然后nacos的InstanceController接收到http请求,调用ServiceManager更新内存注册表。

nacos使用了一个ServiceManager保存了内存注册表,当接收到服务注册请求时,nacos服务端会把服务实例信息写入到ServiceManager里面的内存注册表。

在这里插入图片描述

@RestController
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")
public class InstanceController {...@Autowiredprivate ServiceManager serviceManager;...@CanDistro@PostMapping@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)public String register(HttpServletRequest request) throws Exception {...//请求发送的是Instance信息,接收请求的时解析出来的也是Instancefinal Instance instance = parseInstance(request);//保存客户端注册信息serviceManager.registerInstance(namespaceId, serviceName, instance);return "ok";}...
}

内存注册表

Nacos的ServiceManager保存了一个内存注册表,是一个双层的ConcurrentHashMap,外层的key是namespace(nacos的命名空间),内层的key是group拼上serviceName(服务名),value则是一个Service对象。

在这里插入图片描述

    /*** Map(namespace, Map(group::serviceName, Service)).*/private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();

Service里面并不是直接存放注册上来的服务实例信息,而是一个Map<String, Cluster>类型的clusterMap,Cluster代表集群,nacos这里把不同集群下的实例分组,把同一集群下的实例分到同一个Cluster里面,这样我们就可以就近选取同一集群下的实例。

在这里插入图片描述

Service#clusterMap

    //Service里面保存的又是一个Map,集群名称和Cluster实例的映射,Cluster里面才保存真正的服务实例private Map<String, Cluster> clusterMap = new HashMap<>();

Cluster里面才是真正存放注册上来的服务实例信息,有两个Set集合:

  • Set<Instance> persistentInstances: 持久化实例信息集合
  • Set<Instance> ephemeralInstances:非持久化实例信息集合

在这里插入图片描述

    @JsonIgnoreprivate Set<Instance> persistentInstances = new HashSet<>(); //持久实例集合@JsonIgnoreprivate Set<Instance> ephemeralInstances = new HashSet<>(); //临时实例集合

Instance里面存储的就是服务实例信息,什么ip地址端口号之类的。

内存注册表的更新

Eureka通过三级缓存解决了读写并发冲突,而Nacos则是通过写时复制(copy on write)解决读写并发冲突。

当有服务实例注册上来时,nacos会检查ServiceManger中的内存注册表是否有对应服务的Service对象,如果没有会创建一个空的Service对象放入到内存注册表,如果已经有对应服务的Service对象,则不需要创建。nacos不会马上去修改这个Service对象里面的服务实例信息,而是把该Service对象里面的所有Instance对象,连同新注册上来的Instance对象,收集到一个List中

在这里插入图片描述

这里只会收集所有临时实例,或者所有非临时实例,不会临时和非临时都全部收集上来。然后根据一定的规则生成一个key,把该key与前面的List存入一个内存的临时map中。然后把这个生成的key丢到一个tasks队列中。

在这里插入图片描述

后台会有一个线程轮询这个tasks队列,从队列中取得key,然后根据key从map中取出List,然后把List中的Instance按所属cluster进行分组。分好组后再逐一处理每一组中的Instance,同一组的Instance都是统一集群下的服务实例,再经过一定的处理后,最后会赋值到Cluster对象里面的两个Instance类型的Set集合中的其中一个(临时实例会赋值到ephemeralInstances,非临时实例赋值到persistentInstances),完成写时复制操作。

在这里插入图片描述

值得注意的是,这里nacos使用的了异步写内存注册表,性能是比Eureka要高的。

通知客户端服务变更、服务同步、健康检查

通知客户端服务变更这里与Eureka不一样,Eureka是开启了一个定时任务进行增量更新来感知注册中心服务端的变化。而nacos则是当有服务注册上来,会发送一个UDP请求,通知客户端有服务变更。

在这里插入图片描述

服务同步这nacos与Eureka做法差不多,也是采用了异步同步,不过nacos做了优化,它会攒够一批再一次性同步,也就是做了批量同步的优化。但是超过一定的期限,还是没有攒够一个批次的大小,还是会进行同步。

在这里插入图片描述

健康检查的定时任务是在创建Service的时候启动的,会定时对该Service里面的每个Instance实例进行检查,检查他们的客户端最后一次发送心跳的时间是否超过15s,如果是,则标记为不健康,如果超过30s,则进行服务下线(从内存注册表中剔除,并通知客户端)。

在这里插入图片描述

心跳也是由NamingService开启定时任务定时发送的,这个会在发送服务注册的http请求之前就会开启。

在这里插入图片描述

2.x版本nacos的变化

在nacos2.x以上的版本,如果是临时实例的注册,会走GRPC协议,如果是非临时实例的注册,会走http协议。
在这里插入图片描述
内存注册表的结构也发生了变化,那么与之对应的内存注册表读写的流程(也就是服务注册与服务发现的流程)也发生了变化。

ServiceManager里面不再直接存放双层内存注册表,而是放了一个Service自己与自己对于的map:ConcurrentHashMap<Service, Service> singletonRepository。

在这里插入图片描述

然后每一个连接上来的客户端,都会为它创建一个Client对象,有一个ClientManager管理这些Client对象。

在这里插入图片描述

然后Client里面有一个ConcurrentHashMap<Service, InstancePublishInfo>的map,key是注册上来的服务实例所属的Service,而value则是服务实例信息。

在这里插入图片描述
还有一个ClientServiceIndexesManager存放Service与所有对应的clientId之间的映射。
在这里插入图片描述

因为一个Service可能会有多个服务实例,每个服务实例注册上来时,都会创建一个Client,那么这里记录一个Service对应的有哪些服务实例,Service就可以拿到对应的clientId集合,进而拿到所有的Client对象,而Client对象中有存放了对应的服务实例信息,这样就可以拿到对应的服务实例信息。

于是服务发现的流程就是这样:

在这里插入图片描述

除了内存注册表以及服务注册与发现的变化外,服务同步、通知客户端服务变更、以及健康检查也发生了变化。

服务同步和通知客户端服务变更这两个操作也是异步的,这一点和1.x版本一样。由于2.x的nacos已经换成了GRPC协议,所以这里也是通过发送GRPC协议的请求进行处理,因为GRPC协议底层是长连接的,因此这里不需要再重复建立请求,只需要拿到对应的Connection连接对象,发送一个GRPC请求就可以。

在这里插入图片描述
1.x版本的nacos通过定时任务定时检测服务实例的最后心跳时间,如果超期了就进行服务下线。而2.x版本的nacos由于换成了GRPC协议的长连接,服务端和客户端之间没有再次建立请求的额外开销,因此增加了一个服务端主动探活的操作,如果客户端有响应,那么还是不会进行服务下线的。

在这里插入图片描述

2.x版本的nacos还对异步处理进行了封装,把事件监听机制封装到NotifyCenter中,把一些定时任务、延时任务、异步任务等的处理封装到了NacosTaskExecuteEngine中,这里就不细说了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昇思25天学习打卡营第11天|xiaoyushao

今天分享ResNet50迁移学习。 在实际应用场景中&#xff0c;由于训练数据集不足&#xff0c;所以很少有人会从头开始训练整个网络。普遍的做法是&#xff0c;在一个非常大的基础数据集上训练得到一个预训练模型&#xff0c;然后使用该模型来初始化网络的权重参数或作为固定特征提…

论文阅读:Deep_Generic_Dynamic_Object_Detection_Based_on_Dynamic_Grid_Maps

目录 概要 Motivation 整体框架流程 技术细节 小结 不足 论文地址&#xff1a;Deep Generic Dynamic Object Detection Based on Dynamic Grid Maps | IEEE Conference Publication | IEEE Xplore 概要 该文章提出了一种基于动态网格图&#xff08;Dynamic Grid Maps&a…

操作系统面试知识点总结4

#来自ウルトラマンメビウス&#xff08;梦比优斯&#xff09; 1 文件系统基础 1.1 文件的相关概念 文件是以计算机硬盘为载体的存储在计算机上的信息集合&#xff0c;可以是文本文档、图片、程序。 文件的结构&#xff1a;数据项、记录、文件&#xff08;有结构文件、无结构式…

橙单前端项目下载编译遇到的问题与解决

今天下载orange-admin前端项目&#xff0c;不过下载下来运行也出现一些问题。 1、运行出现下面一堆错误&#xff0c;如下&#xff1a; 2、对于下面这个错误 error Expected linebreaks to be LF but found CRLF linebreak-style 这就是eslint的报错了&#xff0c;可能是原作者…

Python学习笔记44:游戏篇之外星人入侵(五)

前言 上一篇文章中&#xff0c;我们成功的设置好了游戏窗口的背景颜色&#xff0c;并且在窗口底部中间位置将飞船加载出来了。 今天&#xff0c;我们将通过代码让飞船移动。 移动飞船 想要移动飞船&#xff0c;先要明白飞船位置变化的本质是什么。 通过上一篇文章&#xff0…

新手小白的pytorch学习第十四弹------十一、十二、十三弹卷积神经网络CNN的习题

习题编号目录 No 1No 2No 3No 4No 5No 6No 7No 8No 9No 10No 11No 12No 13 练习题主要就是 写代码&#xff0c;所以这篇文章大部分是代码哟~ No 1 What are 3 areas in industry where computer vision is currently being used? No 2 工业异常检测&#xff0c;目标检测 Sea…

第三十四天 复合选择器之后代选择器

常用复合选择器包括 后代选择器、子选择器、并集选择器、伪类选择器 后代选择器 语法 选择器1 选择器2{属性:属性值;} 出现重复组可以用类名进行区别 后代选择器可以无限套娃 父子等级可以是人为创造的

利用GPT4o Captcha工具和AI技术全面识别验证码

利用GPT4o Captcha工具和AI技术全面识别验证码 &#x1f9e0;&#x1f680; 摘要 GPT4o Captcha工具是一款命令行工具&#xff0c;通过Python和Selenium测试各种类型的验证码&#xff0c;包括拼图、文本、复杂文本和reCAPTCHA&#xff0c;并使用OpenAI GPT-4帮助解决验证码问…

spring IOC DI -- IOC详解

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 文章目录 4.2 Ioc 详解4.2.1 Bean的存储Controller(控制器存储)Service (服务存储)Repository(仓库存储)Component(组件存储)Configuration(配置存储) 4.2.2 为什么需要这么多类注解?4.2.3方法…

面试重点---快速排序

快排单趟 快速排序是我们面试中的重点&#xff0c;这个知识点也很抽象&#xff0c;需要我们很好的掌握&#xff0c;而且快速排序的代码也是非常重要&#xff0c;需要我们懂了还不行&#xff0c;必须要手撕代码&#xff0c;学的透彻。 在研究快速排序之前&#xff0c;我们首先…

depcheck 前端依赖检查

介绍 depcheck 是一款用于检测项目中 未使用依赖项 的工具。 depcheck 通过扫描项目文件&#xff0c;帮助你找出未被引用的依赖&#xff0c;从而优化项目。 优势&#xff1a; 简单易用: 仅需几个简单的命令&#xff0c;就能够扫描并列出未使用的依赖项&#xff0c;让你快速了…

GeneCompass:跨物种大模型用于破解基因调控机理

GeneCompass是第一个基于知识的跨物种基础模型&#xff0c;该模型预先训练了来自人类和小鼠的超过1.2亿个单细胞转录组。在预训练过程中&#xff0c;GeneCompass有效整合了四种生物先验知识&#xff0c;以自监督的方式增强了对基因调控机制的理解。对多个下游任务进行微调&…

PlatformIO+ESP32S3学习:通过WIFI与和风天气API获取指定地点的天气情况并显示

1. 硬件准备 你只需要有一个ESP32S3开发板。我目前使用的是&#xff1a; 购买地址&#xff1a;立创ESP32S3R8N8 开发板 2. 和风天气API 2.1. 和风天气介绍 和⻛天气是中国领先的气象科技服务商、国家高新技术 企业&#xff0c;致力于运用先进气象模型结合大数据、人工智能 技术…

成为git砖家(2): gitk 介绍

大家好&#xff0c;我是白鱼。这篇我们介绍 gitk。 gitk 和 fork 界面对比 当我们在 macOS 上执行 brew install git 后&#xff0c; 得到了 git 命令行工具。 然而这条命令并不会安装 gitk. gitk 是 git 自带的图形化界面工具&#xff0c;也可以称为“穷人版 fork”&#xf…

美国演员工会和电视广播艺人工会针对电子游戏发行商的罢工于 7 月 26 日举行

美国演员工会&#xff08;SAG-AFTRA&#xff09;正在对电子游戏发行商进行罢工&#xff0c;以保护演员不被人工智能所利用。经过一年半的谈判&#xff0c;双方仍未达成协议。该工会希望确保人工智能不会被用作利用大型游戏中演员的手段。 他们在网站上声明&#xff0c;“从事电…

搭建自己的金融数据源和量化分析平台(三):读取深交所股票列表

深交所的股票信息读取比较简单&#xff1a; 看上图&#xff0c;爬虫读取到下载按钮的链接之后发起请求&#xff0c;得到XLS文件后直接解析就可以了。 这里放出深交所爬虫模块的代码&#xff1a; # -*- coding: utf-8 -*- # 深圳交易所爬虫 import osimport pandas as pd imp…

fastapi教程(四):做出响应

请求体现的是后端的数据服务能力&#xff0c;而响应体现的是后端向前端的数据展示能力。 一&#xff0c;一个完整的web响应应该包含哪些东西 一个完整的 Web 响应通常包含以下几个主要部分&#xff1a; 1. 状态行- HTTP 版本- 状态码- 状态消息例如&#xff1a;HTTP/1.1 200…

全开源收银系统源码-支付通道

1.收银系统开发语言 核心开发语言: PHP、HTML5、Dart后台接口: PHP7.3后合管理网站: HTML5vue2.0element-uicssjs线下收银台&#xff08;安卓/PC收银、安卓自助收银&#xff09;: Dart3框架&#xff1a;Flutter 3.19.6助手: uniapp商城: uniapp 2.支付通道 智慧新零售收银系统…

一下午连续故障两次,谁把我们接口堵死了?!

唉。。。 大家好&#xff0c;我是程序员鱼皮。又来跟着鱼皮学习线上事故的处理经验了喔&#xff01; 事故现场 周一下午&#xff0c;我们的 编程导航网站 连续出现了两次故障&#xff0c;每次持续半小时左右&#xff0c;现象是用户无法正常加载网站&#xff0c;一直转圈圈。 …