【源码分析】Nacos服务端如何更新以及保存注册表信息?

文章目录


我们知道服务注册到Nacos之后,Nacos是需要对这些服务实例信息进行保存的,那么Nacos是如何保存的呢?
首先我们先分析Nacos的注册表的结构。
我们知道Nacos有namespace,group,cluster三个分级,他们都是用来进行隔离的。
其中Cluster中分为持久化实例和临时实例。他们都是Set类型。
持久化实例即使服务断开也不会从注册表中被删除,而临时实例会,但是临时实例会在每次服务重启的时候都会再一次注册到注册表中。
所以对于Nacos的注册表,大概结构可以猜测为是三层的Map结构,大概结构如下:
Map<namespace,Map<group,Map<clusterName,Cluster>(serviceName)>>
可以分析得到,Nacos的注册表结构为一个namespace将会拥有多个group组,而每个group组中有多个具体的服务。这些服务以集群的方式出现,因此在cluster集群中,会包含最后的具体的实例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那么现在大概了解完毕之后,我们看看这个三层的Map结构是如何创建的。
当我们发送一个HTTP请求到Nacos请求注册一个实例的时候,Nacos的服务端将会调用如下方法:
在这里插入图片描述
而这个方法最后会调用如下方法,这个方法用于创建Servic实例。
在这里插入图片描述

首先是最内层的Map<ClusterName,Cluster>,可以发现,Cluster的内部就是我们刚才说的两个存储临时和持久实例的Set集合。
在这里插入图片描述

而这个Service的结构为
在这里插入图片描述

而我们可以看到,一开始我们会先调用如下方法,来判断这个Service是否已经创建,如果已经创建直接复用即可。
在这里插入图片描述
在这里插入图片描述

可以发现这里的返回结果是Service,也就是当前的String其实就是我们的group了。
下面的这个serviceMap结构,第一个String其实就是我们的namespace了。
第二个String其实就是我们的group。一个group中可以有多个的Service,而Service中可以有多个服务的集群。
在这里插入图片描述

之后我们开始看如何往Service中放入具体的方法
在这里插入图片描述

这里的putService方法就是将我们的服务放入到Map结构中
可以发现为了保证多线程情况下的并发安全,Nacos甚至用了双检索
在这里插入图片描述

然后最后一行从刚才的Map<group,Service>结构中获取到对应的group,然后向这个group中放入 服务名称:服务实例。
然后我们再看看init方法,这个init方法其实就是初始化所有服务中的集群的所有的实例的心跳的。
这将会创建一个定时任务,这个定时任务将会获取到所有实例,并且判断15s内是否发送回了心跳,如果没有的话,会将实例的healthy状态设定为false,而如果超过30s,那么当前实例将会被剔除。
在这里插入图片描述
在这里插入图片描述

了解完毕上述流程,创建完毕Service之后,得到了Service,我们就可以向Service中注入对应的实例了。
在这里插入图片描述

而这里进行添加实例是一个全量添加,先获取目前已有的所有实例,并且再添加上当前新实例。
在这里插入图片描述
在这里插入图片描述

这里有一个Datum,key就是实例名称,value说就是实例具体的信息了。
在这里插入图片描述

而这个allIps就可以获取到Cluster中所有的实例
在这里插入图片描述

并且这里就开始区分到底是使用CP还是使用AP了。
在这里插入图片描述

此时已经完成了从Cluster中获取到所有实例了,那么此时我们就是对他进行一些处理转换即可,那么此时就已经拿到了内存中的全量的实例的信息。
特别注意这里还考虑到了一个CopyOnWrite的思想。
我们知道实例信息是存储在内存中的,此时他先获取到了所有的实例,然后再创建一个新的集合用于存储实例,而不是直接再内存中的Set进行修改添加。
在这里插入图片描述

这个方法执行完毕之后,我们就已经将新添加的实例和内存中已经拥有的实例都获取到了。
之后我们就要将这些所有实例放入到cluster中了,但是我们还得选择实例的两种模式。
在这里插入图片描述

而这里很明显是一个委托方法,走的是DelegateConsistencyServiceImpl类,具体调用Distro还是Raft需要进行实例类型的判断。
在这里插入图片描述

此时会根据key的类型,来判断是放入到临时还是持久服务中。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里如果选用的是临时实例,那么就是使用Distro来创建,也就是使用AP协议,而如果是持久实例,则是使用Raft。
因为我们知道Raft和Paxos这两个协议都是一致性协议,都是选择CP的。

//AP:EphemeralConsistencyService --->Distro
//CP:PersistentConsistencyService --->Raft

所以,在这里就已经产生了我们的分歧,具体使用AP还是CP取决于你使用的协议。
在这里插入图片描述

此时我们先分析,使用AP协议的情况,也就是使用Distro的情况。
那由于保证的是可用性而非一致性,那么其实我们可以使用定时任务或者队列的方式来异步加载这些实例。
而Nacos也正是这么做的。
在这里插入图片描述
在这里插入图片描述

这里可以看到,又一次的使用了Datum,其中value就是对应的所有的实例,而key就是服务。
在这里插入图片描述

这里操作了这么多,其实都只是再另一个内存中进行操作这些实例,还并没有将这些新实例放入到我们的内存中,也就是Nacos的那个set结构中,那个存储具体实例信息的set中。也就是此时还是没有完成实例的注册。
再上面看到的notifier中才是真正的开始执行完成注册事件的地方。
在这里插入图片描述

而再notifier的run方法中,当触发CHANGE事件的时候,就会调用如下方法,因为此时阻塞队列已经收到了任务,马上就开始执行逻辑,而如果阻塞队列没有收到任务,那么就会一直阻塞但是不消耗性能。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面这张图就是具体的更新内存中的实例,并且还会发布一个服务变化事件。
在这里插入图片描述

进入到这一步就可以根据是否是临时节点判断应该放入的是临时还是持久Set集合中。
而服务发现查找临时实力的时候就会从这个cluster的ephemeralInstances中进行获取。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Llama 2 with langchain项目详解(一)

Llama 2 with langchain项目详解(一) 2023年2月25日,美国Meta公司发布了Llama 1开源大模型。随后,于2023年7月18日,Meta公司发布了Llama 2开源大模型,该系列包括了70亿、130亿和700亿等不同参数规模的模型。相较于Llama 1,Llama 2的训练数据增加了40%,上下文长度提升至…

uniapp 返回上一页并刷新

如要刷新的是mine页面 在/pages/mine/improveInfo页面修改信息&#xff0c;点击保存后跳转到个人中心&#xff08;/pages/mine/index&#xff09;页面并刷新更新数据 点击保存按钮时执行以下代码&#xff1a; wx.switchTab({url: /pages/mine/index }) // 页面重载 let pages …

出现Error: Cannot find module ‘compression-webpack-plugin‘错误

错误&#xff1a; 解决&#xff1a;npm install --save-dev compression-webpack-plugin1.1.12 版本问题

powerdesigner各种字体设置;preview字体设置;sql字体设置

1.设置左侧菜单&#xff1a; 步骤如下&#xff1a; tools —> general options —> fonts —> defalut UI font ,选择字体样式及大小即可&#xff0c;同下图。 2.设置preview字体大小&#xff08;sql预览&#xff09; 步骤如下&#xff1a; tools —> general o…

无涯教程-Perl - chop函数

描述 此函数从EXPR,LIST的每个元素或$_(如果未指定值)中删除最后一个字符。 语法 以下是此函数的简单语法- chop VARIABLEchop( LIST )chop返回值 此函数返回从EXPR中删除的字符,并且在列表context中,从LIST的最后一个元素中删除该字符。 例 以下是显示其基本用法的示例…

汽配企业如何利用MES管理系统解决生产防错难题

汽车配件制造业是一个高效率、低成本、高质量的生产领域&#xff0c;但同时也面临着一系列的挑战。其中最为突出的挑战之一是如何在生产过程中避免错误&#xff0c;提高产品的合格率。本文将介绍汽车配件的制造特点以及如何通过MES管理系统解决方案实现生产防错&#xff0c;从而…

高中生python零基础怎么学,python高中生自学行吗

这篇文章主要介绍了高中学历学python好找工作吗&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 学习python的第九天 根据我们前面这几天的学习&#xff0c;我们掌握了Python的…

检查网站是HTTP那种协议与获取域名的ipv6地址

前言 最近在做HTTPS的应用&#xff0c;可能需要使用ipv6的地址做SLB&#xff0c;但是怎么检查配置正确&#xff0c;总不能每次都看日志吧&#xff0c;实际上客户端也很容易查看&#xff0c;总结工作经验。 检查HTTP协议版本 笔者想到了使用浏览器方式&#xff0c;或者抓包&a…

docker中的jenkins去配置sonarQube

docker中的jenkins去配置sonarQube 1、拉取sonarQube macdeMacBook-Pro:~ mac$ docker pull sonarqube:8.9.6-community 8.9.6-community: Pulling from library/sonarqube 8572bc8fb8a3: Pull complete 702f1610d53e: Pull complete 8c951e69c28d: Pull complete f95e4f8…

React Dva 操作models中的subscriptions讲述监听

接下来 我们来看一个models的属性 之前没有讲到的subscriptions 我们可以在自己有引入的任意一个models文件中这样写 subscriptions: {setup({ dispatch, history }) {console.log(dispatch);}, },这样 一进来 这个位置就会触发 这里 我们可以写多个 subscriptions: {setup…

opencv基础-29 Otsu 处理(图像分割)

Otsu 处理 Otsu 处理是一种用于图像分割的方法&#xff0c;旨在自动找到一个阈值&#xff0c;将图像分成两个类别&#xff1a;前景和背景。这种方法最初由日本学者大津展之&#xff08;Nobuyuki Otsu&#xff09;在 1979 年提出 在 Otsu 处理中&#xff0c;我们通过最小化类别内…

11. Redis基础知识

文章目录 一、概述二、数据类型STRINGLISTSETHASHZSET 三、数据结构字典跳跃表 四、使用场景计数器缓存查找表消息队列会话缓存分布式锁实现其它 五、Redis 与 Memcached数据类型数据持久化分布式内存管理机制 六、键的过期时间七、数据淘汰策略八、持久化RDB 持久化AOF 持久化…

AcWing 379. 捉迷藏(最小路径点覆盖匈牙利算法)

输入样例&#xff1a; 7 5 1 2 3 2 2 4 4 5 4 6输出样例&#xff1a; 3 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N220; int n,m,t; int d[N][N],vis[N]; int match[N]; bool find(int x){for(int i1;i<n;i){if(d[x][i]&&…

react icon ant简单使用

refer&#xff1a; 文字提示 Tooltip - Ant Design 1.首先保证已经引入了Ant 2.在组件&#xff08;页面&#xff09;引入tooltip import { Form, Tooltip } from antd; 3.在合适的位置使用tooltip&#xff1a; <span>寿命 <Tooltip title"这是寿命的说明&quo…

java.lang.UnsupportedClassVersionError TestCase

JavaFramework-JDK6.jar 放到JDK17运行没有问题 JavaFramework源码放到JDK17环境下编译出来的JavaFramework-JDK17.jar JavaFramework-JDK17.jar 放到JDK17运行没有问题 JavaFramework-JDK17.jar 放到JDK8运行没有问题&#xff0c;这个好像不对啊&#xff0c;可能之前编译设置…

数组根据属性去重

利用reduce函数处理&#xff0c;直接上代码&#xff01; let data [{name:晓明,id:1},{name:德华,id:2},{name:德华,id:2},{name:晓明,id:1},] var obj {}; let arr data.reduce(function (item, next) {obj[next.id] ? : obj[next.id] true && item.push(next)…

Unity CanvasGroup组件

文章目录 1. 简介2. 组件属性2.1 Alpha(透明度)2.2 Interactable(是否为可交互)2.3 Blocks Raycasts(是否接受射线监测)2.4 Ignore Parent Groups(忽视上层的画布组带来的影响) 1. 简介 CanvasGroup(画布组) 组件&#xff0c;可集中控制整组 UI 元素(自身和所有子物体)的某些属…

ansible安装及rhel8仓库配置

目录 一、本地仓库 问题&#xff1a; 解决&#xff1a; 1.创建一个仓库&#xff1a; 内容&#xff1a; 2.挂载&#xff1a; 挂载&#xff1a; 测试&#xff1a; 3.或者直接使用阿里云的源 二.配置ansible仓库 1.下载&#xff1a; 2.检查 一、本地仓库 问题&#xff1a; 当…

Jmeter-获取接口响应头(Response headers)信息进行关联

文章目录 Jmeter-获取接口响应头&#xff08;Response headers&#xff09;信息进行关联使用正则表达式提取器将Set-Cookie的值提取出来在其余接口中关联该提取信息运行查看关联是否成功 Jmeter-获取接口响应头&#xff08;Response headers&#xff09;信息进行关联 获取某一…

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28‘ not found

某项目中&#xff0c;我要给别人封装一个深度学习算法的SDK接口&#xff0c;运行在RK3588平台上&#xff0c;然后客户给我的交叉编译工具链是 然后我用他们给我的交叉编译工具链报下面的错误&#xff1a; aarch64-buildroot-linux-gnu-gcc --version /data/chw/aarch64/bin/cca…