nacos源码分析==服务订阅-服务端推送被订阅者最新信息给订阅者

news2024/11/16 1:30:33

上一篇讲到客户端发送请求到服务端进行服务注册,注册后,服务端会发出两个事件,第一个事件会触发另一个ServiceChangedEvent,这个事件被com.alibaba.nacos.naming.push.v2.NamingSubscriberServiceV2Impl#onEvent

监听,监听到后将该客户端最新的信息推送给订阅该客户端的其他客户端。

这个推送是怎么完成的?

首先,客户端必须告诉服务端它订阅了哪些客户端

试了下貌似是A首次调用B之后,之后A中定时执行的UpdateTask才会去拉取被调用的B服务的信息,意思是A调用一次B之后就认为订阅了这个服务。

比如我这里ruoyi system的定时拉取ruoyi file的信息

 

 

 此时ruoyi file的端口是3000

 此时如果我停掉ruoyi file 并更改下端口重启,ruoyi system下次拉取到的应该会变,但实际上是我一停止ruoyi file, ruoyi system就会收到来自服务端的通知,收到通知后,依然会有UpdateTask去拉取ruoyi file的信息

 ruoyi file的端口改成9301之后重启,ruoyi system会再次收到来自服务端的推送

ruoyi system的下一次UpdateTask就会获取到ruoyi file新的端口 

 此时我如果再次将ruoyi file停掉,服务端应该会产生一个ServiceChangedEvent并且被com.alibaba.nacos.naming.push.v2.NamingSubscriberServiceV2Impl#onEvent监听到,

最终向订阅ruoyi file的其他客户端推送消息是在

com.alibaba.nacos.naming.push.v2.task.PushExecuteTask#run

    @Override
    public void run() {
        try {
            PushDataWrapper wrapper = generatePushData();
            ClientManager clientManager = delayTaskEngine.getClientManager();
//或者需要推送给哪些客户端
            for (String each : getTargetClientIds()) {
                Client client = clientManager.getClient(each);
                if (null == client) {
                    // means this client has disconnect
                    continue;
                }
                Subscriber subscriber = clientManager.getClient(each).getSubscriber(service);
//推送
                delayTaskEngine.getPushExecutor().doPushWithCallback(each, subscriber, wrapper,
                        new ServicePushCallback(each, subscriber, wrapper.getOriginalData(), delayTask.isPushToAll()));
            }
        } catch (Exception e) {
            Loggers.PUSH.error("Push task for service" + service.getGroupedServiceName() + " execute failed ", e);
            delayTaskEngine.addTask(service, new PushDelayTask(service, 1000L));
        }
    }

com.alibaba.nacos.naming.push.v2.executor.PushExecutorRpcImpl#doPushWithCallback

com.alibaba.nacos.core.remote.RpcPushService#pushWithCallback

可以发现,不管被订阅者上线或者下线,都会给订阅者推送,区别就是request中的ServiceInfo的hosts中存的IP端口变了,我这只有一个实例,现在后hosts就是空的

 被订阅者上线,通知订阅者,hosts属性中带上了IP和端口

 

总结
服务端接收到服务注册请求后,发布了ClientRegisterServiceEvent客户端注册事件
ClientRegisterServiceEvent事件被ClientServiceIndexesManager订阅后发布ServiceChangedEvent服务变更事件
ServiceChangedEvent被NamingSubscriberServiceV2Impl订阅并创建PushDelayTask并被PushExecuteTask执行,负责向订阅该服务的客户端发起推送serviceInfo请求
推送的请求被NamingPushRequestHandler处理并发布InstancesChangeEvent,最终回调AbstractEventListener
————————————————
版权声明:本文为CSDN博主「宽仔的代码之路」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guntun8987/article/details/125570748

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

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

相关文章

16. 条件控制

总体来说,条件控制的效果类似c/c/c#/java中的,只不过在语法格式的层面上存在一定的差异。 1. if条件语法格式 if condition_1:...elif condition_2:...else:...1、python 中用 elif 代替了 c/c中的 else if,所以if语句的关键字为&#xff1a…

高性能排序函数实现方案

如C语言的qsort()、Java的Collections.sort(),这些排序函数如何实现? 1 合适的排序算法? 线性排序算法的时间复杂度较低,适用场景特殊,通用排序函数不能选择。 小规模数据排序,可选时间复杂度O(n^2)算法大…

【算法】滑动窗口

目录1.概述2.算法框架3.应用本文参考: LABULADONG 的算法网站 1.概述 (1)滑动窗口可以用以解决数组/字符串的子元素相关问题,并且可以将嵌套的循环问题,转换为单循环问题,从而降低时间复杂度。故滑动窗口算…

【数据分析】(task5)数据建模及模型评估

note 文章目录note一、建立模型二、模型评估2.1 交叉验证2.2 混淆矩阵/recall/accuracy/F12.3 ROC曲线三、Pyspark进行基础模型预测时间安排Reference一、建立模型 下载sklearn的命令pip install scikit-learn。 from sklearn.model_selection import train_test_split impor…

ARP渗透与攻防(二)之断网攻击

ARP断网攻击 系列文章 ARP渗透与攻防(一)之ARP原理 1.环境准备 kali 作为ARP攻击机,IP地址:192.168.110.26 MAC地址:00:0c:29:fc:66:46 win10 作为被攻击方,IP地址:192.168.110.12 MAC地址:1c:69:7a:a…

Tkinter的Entry与Text

Tkinter界面设计之输入控件Entry以及文本框控件Text。 目录 一、放置控件 1. pack()函数 2. place()函数 3. grid()函数 二、简单控件 1. Entry输入控件 1.1 tk.StringVar()函数:接收一个字符串 1.2 tk.Entry()函数:设置一个输入控件E 2. Text文…

CMake多文件编译

之前学习ceres-solver中的3d相关的源码的时候,发现对于CMake多文件工程编译中对于CMakeLists.txt的编写和处理的理解运用还是比较模糊,这里整理梳理一下对于不同文件夹数量如何使用。 参考文章: CMake使用详解二(多文件编译&…

maya常用操作

1:重置工作区。2:切换视图。按空格切换视图。3:未选中状态,按shift,再点右键,可以打开交互式创建。这样可以在栅格上创建想要的大小。不选中交互式创建的话,创建的是默认未知。默认未知为正中间…

linux系统中利用QT实现车牌识别的方法

大家好,今天主要和大家分享一下,如何利用QT实现车牌识别的方法。 目录 第一:车牌识别基本简介 第二:车牌识别产品申请 第三:百度车牌识别API接口 第四:车牌识别综合测试 第一:车牌识别基本简…

Scala快速入门

Scala简介 Scala是一门现代的多范式编程语言,平滑地集成了面向对象和函数式语言的特性。Scala运行于Java平台(JVM,Java 虚拟机)上,并兼容现有的Java程序,Scala代码可以调用Java方法,访问Java字…

ArcGIS Pro脚本工具(17)——生成多分式标注

​朋友们,你们知道ArcGIS里面分式标注的四种写法么? 放错图了,是这个 分式标注的四种形式我们可以把这类叫分式标注,网上也有博主分享过如何在ArcGIS中制作这类标注,但我觉得仍有一些不足。 一是基本都使用VB编写&…

中文问题相似度挑战赛

赛题概要 请本赛题排行榜前10位的队伍,通过作品说明提交源代码,模型以及说明文档,若文件过大,可发送至官网邮箱AICompetitioniflytek.com, 若截止时间内为提交,官方会通过电话联系相关选手,若未接到通知或…

WPF作图神器Interactive DataDisplay的初步使用

文章目录安装初步使用安装 Interactive DataDisplay是一款比较优秀的C#绘图控件,尽管与一些商业控件还有不小的差距,关键是开源免费轻量。 在VS中安装控件十分简单,本测试基于Net Core5.0,在VS的菜单栏->工具->NuGet包管理…

HomeLab 常用工具一:filebrowser

前言在实际使用过程中,我们通常都有基于WEB 的文件操作需求(例如从一台陌生设备上想打开看一下,图片等),和nextcloud 相比 filebrowser 更为轻巧也更为方便。一、filebrowser 安装这里基于docker 安装和使用&#xff0…

Prometheus 动态拉取监控服务

Prometheus 版本 2.41.0 平台统一监控的介绍和调研直观感受PromQL及其数据类型PromQL之选择器和运算符PromQL之函数Prometheus 配置身份认证Prometheus 动态拉取监控服务 我们在以前的实例中配置Prometheus 的target 都是手动配置,这在监控目标少的情况下还可以接受…

【基础】BMP格式

BMP格式位图 (BMP)简介格式1.1图和调色板的概念1.2 bmp文件格式1.2.1 位图文件头 14字节1.2.2 位图信息头 40字节1.2.3 调色板1.2.4 注意位图 (BMP)简介 BMP取自位图Bitmap的缩写,也称为DIB(与设备无关的位图),是一种独立于显示器…

【苹果家庭群发推】软件keychain中刚打开的证书下载的证书文件要决不会报错 UNTimeIntervalNotificationTrigge

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

linux入门---linux基本指令

目录标题云服务器选择云服务器购买xshell下载如何登陆云服务器Linux的新建与删除新建删除云服务器选择 学习linux的时候云服务器是一个非常重要的工具,那么我们在购买云服务器的时候有很多选择比如说:华为云,腾讯云,阿里云等等&a…

活动星投票网络文明公益广告网络评选微信的投票方式线上免费投票

“网络文明公益广告”网络评选投票_不记名投票小程序_投票帮手免费畅享_扫码投票微信小程序手机互联网给所有人都带来不同程度的便利,而微信已经成为国民的系统级别的应用。现在很多人都会在微信群或朋友圈里转发投票,对于运营及推广来说找一个合适的投票…

ROS2机器人编程简述humble-第三章-PERCEPTION AND ACTUATION MODELS .1

书中,第三章主题:First Behavior: Avoiding Obstacles with Finite States Machines本节旨在应用到现在为止所展示的一切来创建看似“聪明”的行为。这个练习将介绍的许多东西结合起来,并展示使用ROS2编程机器人的效率。此外,将解…