全网最细的nacos服务端服务注册:没有之一

2024-02-05 00:28

本文主要是介绍全网最细的nacos服务端服务注册:没有之一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

服务端注册入口

BaseRpcServer
image.png
由于有@PostConstrct注解,也就是说在构造方法后会执行,startServer会由它的子类BaseGrpcServer.startServer重写

BaseGrpcServer.startServer

image.png
addServices:
image.png
其中grpcCommonRequestAcceptor和grpcBiStreamRequestAcceptor就是实现了nacos_grpc_service.proto的两个子处理类
public class GrpcRequestAcceptor extends RequestGrpc.RequestImplBase {
�public class GrpcBiStreamRequestAcceptor extends BiRequestStreamGrpc.BiRequestStreamImplBase {

对应nacos_grpc_service.proto中的两个方法处理

service Request {// Sends a commonRequestrpc request (Payload) returns (Payload) {}
}service BiRequestStream {// Sends a biStreamRequestrpc requestBiStream (stream Payload) returns (stream Payload) {}
}

GrpcRequestAcceptor.request

image.png
image.png
这里最终会调用到InstanceRequestHandler.handle方法,不用猜基本上就知道要做什么,实例相关的操作

InstanceRequestHandler.handle

image.png
image.png
最终会调用到EphemeralClientOperationServiceImpl.registerInstance

EphemeralClientOperationServiceImpl.registerInstance

image.png
具体做了几件事:

  1. 从ServiceManger里面通过service来获取service(包含namespace,group,name,ephemeral=true),我们来看一下ServiceManger具体是什么样子的存储结构?

image.png
更加形象的是这样:
image.png

  1. 从ClientManger通过clientId获取Client,这里我们来看一下clientId、ClientManger、Client分别是什么?

ClientId:
image.png
ClientManger: 专门用来管理客户端连接的组件
image.png
Client:客户端信息
上图中connectionBasedClientManger里面的clients属性 ,里面存储的key、value,key为clientId,value为客户端信息,也就是上面的ConnectionBasedClient
image.png

  1. 创建发布信息,并将发布信息放到ConnectionBasedClient中

image.png
将Service和publishInfo放到publishers中,实际的数据如图:
image.png

  1. 发布ClientRegisterServiceEvent�事件,具体需要看看这个事件是由谁来处理,其实很好找,看看这个那个类使用了这个事件就行,最终找到了ClientServcieIndexesManger

ClientServiceIndexesManager.handleClientOperation

image.png
image.png
image.png
这里总结一下做了几件事:

  1. 将service以及clientId放到publisherIndexes中,存储的格式就是<Service,Set>,更加形象的图如图:

image.png

  1. 发布ServiceChangedEvent事件,这个事件最终会被NamingSubscriberServiceV2Impl给处理

NamingSubscriberServiceV2Impl.onEvent

image.png
这里会将事件封装成PushDelayTask,然后使用delayTaskEngine,这里的delayTaskEngine是PushDelayTaskExecute

PushDelayTaskExecuteEngine�.addTask

PushDealyTaskExecuteEngine继承了NacosDelayTaskExecuteEngine,最终会调用到父类的addTask方法
image.png
image.png
image.png
其实这里比较简单,就是把task加入到ConcurrentHashMap里面去,key就是Servcie,value就是pushDelayTask

加入到这个ConcurrentHashMap肯定是要被处理的,那我们看看是在哪里被处理?

  1. NacosDelayTaskExecuteEngine在构造方法里面创建了一个定时调度的线程池,里面有一个被定时调度的任务,每隔100ms被调度执行

image.png
image.png

  1. NacosDelayTaskExecuteEngine.processTask

image.png
遍历上面的concurrentHashMap,然后通过taskkey然后找到处理类,因为我们没有设置,所以这里的NacosTaskProcessor就是子类PushDelayTaskExecuteEnginge里面设置的PushDelayTaskProcessor
image.png

  1. PushDelayTaskProcessor.process

image.png
image.png
这里的NacosExecuteTaskExecuteEngine还是需要详细分析一下

到这里用图总结一下从NamingSubscriberServiceV2Impl.onEvent到此处:
image.png

NacosExecuteTaskExecute.addTask

NacosExecuteTaskExecute.addTask
image.png
逻辑比较简单,先看看它有没有对应的NacosTaskProcessor,实际就是没有的(key没有,默认也没有设置),接下来就直接通过getWorker来处理

image.png
从executeWorkers中取一个TaskExecuteWorker给这个task来执行,所以我们要看一下这个executeWorkers到底是什么?
image.png
这里的TaskExecuteWorker就是一个单线程执行器

TaskExecuteWorker.process

image.png
image.png
又是似曾相识的套路,往queue里面塞东西,那具体在哪里处理的?
里面有内部单线程处理:
image.png
也就说最终还是会调用到传进来task的run方法,看到这里感觉无比的累啊,应该快结束了

到这里也拿一张图总结一下:
image.png

PushExecuteTask.run

image.png
image.png
image.png
image.png
总结一下做了几件事:

  1. 生成推送数据:generatePushData
    1. 通过serviceIndexesManger + service能找到service对应那些clientId

image.png

  1. 通过clientManger+ clientId能找到client对应的发布信息publishers,再通过publishers+service能找到这个service对应的Instance

image.png
我们来看一下实际debug得到的数据:
image.png

  1. 往serviceClusterIndex.put(service, clusters)

image.png

  1. 往serviceDataIndexes.put(service, serviceInfo)

image.png

  1. 推送给目标客户端
    1. getTargetClients: 通过ClientServiceIndexManger+ service来获取这个订阅这个service所有clientId

image.png

  1. 遍历订阅这个service的所有clientId,通过ClientManger+ clientId找到这个客户端,再通过这个客户端的subsribers+ service就能知道这个客户端订阅这个service的详情了

image.png

  1. 最后调用doPushWithCallback往订阅客户端推送数据

这篇关于全网最细的nacos服务端服务注册:没有之一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/679249

相关文章

jupyter代码块没有运行图标的解决方案

《jupyter代码块没有运行图标的解决方案》:本文主要介绍jupyter代码块没有运行图标的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录jupyter代码块没有运行图标的解决1.找到Jupyter notebook的系统配置文件2.这时候一般会搜索到

SpringCloud之consul服务注册与发现、配置管理、配置持久化方式

《SpringCloud之consul服务注册与发现、配置管理、配置持久化方式》:本文主要介绍SpringCloud之consul服务注册与发现、配置管理、配置持久化方式,具有很好的参考价值,希望... 目录前言一、consul是什么?二、安装运行consul三、使用1、服务发现2、配置管理四、数据持久化总

Spring Cloud之注册中心Nacos的使用详解

《SpringCloud之注册中心Nacos的使用详解》本文介绍SpringCloudAlibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringClo... 目录Naacos服务注册/服务发现引⼊Spring Cloud Alibaba依赖引入Naco编程s依

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

电脑没有仿宋GB2312字体怎么办? 仿宋GB2312字体下载安装及调出来的教程

《电脑没有仿宋GB2312字体怎么办?仿宋GB2312字体下载安装及调出来的教程》仿宋字体gb2312作为一种经典且常用的字体,广泛应用于各种场合,如何在计算机中调出仿宋字体gb2312?本文将为您... 仿宋_GB2312是公文标准字体之一,仿China编程宋是字体名称,GB2312是字php符编码标准名称(简

SpringBoot实现websocket服务端及客户端的详细过程

《SpringBoot实现websocket服务端及客户端的详细过程》文章介绍了WebSocket通信过程、服务端和客户端的实现,以及可能遇到的问题及解决方案,感兴趣的朋友一起看看吧... 目录一、WebSocket通信过程二、服务端实现1.pom文件添加依赖2.启用Springboot对WebSocket

Nacos客户端本地缓存和故障转移方式

《Nacos客户端本地缓存和故障转移方式》Nacos客户端在从Server获得服务时,若出现故障,会通过ServiceInfoHolder和FailoverReactor进行故障转移,ServiceI... 目录1. ServiceInfoHolder本地缓存目录2. FailoverReactorinit

Nacos集群数据同步方式

《Nacos集群数据同步方式》文章主要介绍了Nacos集群中服务注册信息的同步机制,涉及到负责节点和非负责节点之间的数据同步过程,以及DistroProtocol协议在同步中的应用... 目录引言负责节点(发起同步)DistroProtocolDistroSyncChangeTask获取同步数据getDis

豆包 MarsCode 不允许你还没有女朋友

在这个喧嚣的世界里,爱意需要被温柔地唤醒。为心爱的她制作每日一句小工具,就像是一场永不落幕的浪漫仪式,每天都在她的心田播撒爱的种子,让她的每一天都充满甜蜜与期待。 背景 在这个瞬息万变的时代,我们都在寻找那些能让我们慢下来,感受生活美好的瞬间。为了让这份浪漫持久而深刻,我们决定为女朋友定制一个每日一句小工具。这个工具会在她意想不到的时刻,为她呈现一句充满爱意的话语,让她的每一天都充满惊喜和感动

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏 览器需要不断的向服务器发出请求,然而HTTP