IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Nacos作为注册中心时Consumer更新Provider的机制 -> 正文阅读

[网络协议]Nacos作为注册中心时Consumer更新Provider的机制

一、NacosRegistry

Consumer端启动时,通过NacosRegistry中的doSubscribe(...)方法,往Nacos服务端发起注册及获取Provider信息:

方法doSubscribe(URL, NotifyListener)中根据Consumer端的url生成对应的Provider服务名称,如此时consumer的url如下:

consumer://192.168.22.198/cn.raysonblog.shopserviceprovider.service.RpcShopService?application=shop-service-consumer&category=providers,configurators,routers&dubbo=2.0.2&generic=false&interface=cn.raysonblog.shopserviceprovider.service.RpcShopService&lazy=false&logger=log4j2&methods=sayHello,getConfigServiceName&pid=397&qos.enable=false&release=2.7.3&side=consumer&sticky=false&timestamp=1629807903321

此时生成的Provider服务名称serviceNames为:

providers:cn.raysonblog.shopserviceprovider.service.RpcShopService::

二、NacosNamingService

在方法doSubscribe(URL, NotifyListener, Set<String>)中通过namingService.getAllInstances(serviceName)获取当前Consumer对应服务的所有Provider节点,namingService代表的类为NacosNamingService?,在该类中会通过getAllInstances(...)方法调用HostReactor的getServiceInfo方法获取ServiceInfo对象:

三、HostReactor

getServiceInfo(...)方法会判断本地是否已经有Provider节点信息,如果没有则通过updateServiceNow(...)立即从Nacos服务获取:

?以下将立即获取更新及将更新加到定时任务中分别说明。

1、立即获取更新

updateServiceNow(...)方法中是通过HTTP请求向Nacos获取最新的配置信息:

此处的serverProxy对象是NamingProxy类的实例,queryList(...)方法:

会调用Nacose服务的接口“/nacos/v1/ns/instance/list”获取数据,传入的参数:

  • namespaceId:指定获取配置的命名空间,dubbo可以通过配置项dubbo.registry.address中的nacos地址中增加namespace参数进行指定,如下所示:

  • serviceName:当前Consumer应用的要获取的Provider的服务名称,Consumer自动生成,类似如下所示:
DEFAULT_GROUP@@providers:cn.raysonblog.shopserviceprovider.service.RpcShopService::
  • clusters:暂时不清楚,代码中也没有注释,默认情况下是new了一个空的ArrayList<String>,到这里时该参数的值ArrayList中的值按英文逗号分隔后的拼接:StringUtils.join(clusters, ","),因而其值还是空字符串"";
  • udpPort:用于接收Nacos的UDP连接的端口,Nacos服务端往当前应用发送推送消息时,就往该端口推送,接收UDP的实现为PushReceiver,后面单独介绍该实现;
  • clientIp:当前应用所在服务器的IP地址,用于接收Nacos服务的UDP推送等;
  • healthOnly:用于指定是否只获取健康的Provider示例,默认值为false,跟了一下queryList方法的调用,共有三个地方且都在HostReactor中,传入的值都是false,因而目前还没有发现可以通过配置修改该值;

调用Nacos服务获取Provider信息的接口,可能成功也可能失败,如果失败则不更新Provider的信息;如果成功则会比较本地与从服务端获取的进行刷新时间的比较,以便于确认其是否为过期服务等验证,验证通过后才会使用新的Provider信息更新本地的Provider信息,如下HostReactor.processServiceJSON(String)方法所示:

?2、定时更新配置

定时更新是方法scheduleUpdateIfAbsent(serviceName, clusters)调用其中的addTask方法增加到定时任务中:

public synchronized ScheduledFuture<?> addTask(UpdateTask task) {
    return executor.schedule(task, DEFAULT_DELAY, TimeUnit.MILLISECONDS);
}

初次执行周期延迟为DEFAULT_DELAY,默认值为1000,即1秒。

?其中UpdateTask为真正执行的线程,检查是否有新的Provider节点信息,实现如下:

?通过UpdateTask的线程实现可以得知,Nacos作为注册中心时,Consumer是通过HostReactor中的UpdateTask线程间隔10秒去服务端拉取最新的Provider信息实现的,而不是准实时或者推送的方式

四、EventDispatcher

HostReactor.processServiceJSON(String)方法会调用EventDispatcher.serviceChanged(ServiceInfo)方法,将变化的ServiceInfo加入到名为changedServices的LinkedBlockingQueue队列中,然后会通过EventDispatcher中的线程Notifier进行处理:

EventListener会调用Dubbo服务提供者变更通知NotifyListener的实现类RegistryDirectory,通知Dubbo Consumer端发起对这些可用Provider的连接,如果原来有连接也会重新发起连接,后面会有操作步骤及日志展示。

五、PushReceiver

PushReceiver为Consumer接收Nacos服务端UDP通知的监听器,以单独的线程进行监听,分为三种消息类型:dom、service及dump,dom及service消息类型都是服务端给Consumer发送消息,如Provider节点变更消息,然后通过hostReactor.processServiceJSON(...)处理这些信息,如下图红枉中的代码所示;dump消息类型为服务端希望获取Consumer的中现在的Provider信息:

但是不论我是增加新的Provider还是断掉Provider,该线程就从来没有读取到数据,说明Nacos服务端没有通过UDP消息的方式往客户端推送消息,那问题来了,Nacos服务端会在什么时候触发UDP通知呢?

六、新增加Provider的日志分析

现在已经启动一台Provider以及一台Consumer,现在观察一下新增加Provider时,Consumer在获取到新的Provider,除了对新节点进行重连以下,是否会重新对已经存在Provider再次发起连接。

启动第二台Provider 2

先看一下启动第二个Provider节点的启动日志:

55分19秒启完成,55分20秒显示成功注册到Nacos。

查看Consumer此时的日志变化:

?Consumer在55分21秒的时候显示收到Nacos的通知,并在同一秒的时间成功与Provider连接。

通过上面的日志可以看到,Provider在启动成功后的秒钟之内,Consumer收到通知并成功与Provider进行连接。

与此同时Provider 1的日志控制台有重新注册到Nacos的日志:

启动第三台Provider 3

先看一下启动第三个Provider节点的启动日志:

?56分17秒启完成,56分18秒显示成功注册到Nacos。

查看Consumer此时的日志变化:

Consumer在56分21秒的时候显示收到Nacos的通知,并在同一秒的时间成功与Provider连接。

通过上面的日志可以看到,Provider在启动成功后的秒钟之内,Consumer收到通知并成功与Provider进行连接。

与此同时Provider 1的日志控制台有重新注册到Nacos的日志:

与此同时Provider 2的日志控制台有重新注册到Nacos的日志:

?

通过以上几个Provider的加入及日志分析,说明Consumer有重新往原来已经建立了连接的Provider发起了建立连接的请求。?

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-26 12:28:31  更:2021-08-26 12:29:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:16:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码