概述
文章目录
- Nacos服务注册原理源码
- 客户端
- 服务注册测试单元
- Nacos自动装配
- 服务注册
- 服务端
- 服务注册
- 集群同步
Nacos服务注册原理源码
客户端
服务注册测试单元
我们先看一下Nacos客户端给出的服务注册的测试单元代码
测试单元中主要做的事情:
- 构建服务Instance对象
- 通过工厂创建NamingService对象
- Instance向NamingService(注册中心)注册
- 通过serviceName向注册中心(NamingService)获取实例列表信息
测试单元中我们知道客户端根据服务的ip、端口、权重、元数据等参数构建了一个Instance
的注册实例对象,
然后根据NacosFactory
通过给定的配置创建了一个NamingService
,通过NacosFactory#createNamingService
代码,可以看到实际上是通过反射创建了NacosNamingService
接下来我们来看下注册实例的代码
registerInstance
是个重载方法,另一个registerInstance
方法给服务指定了默认的groupName,通过代码可以看到注册方法调用的具体对象是clientProxy,具体类型为NamingClientProxyDelegate
,该对象在NamingService#init
方法中进行的赋值操作。
我们看下该方法调用代码,首先根据实例是否临时实例,判断注册请求是通过grpc还是http闹到客户端代理对象来注册(实例默认就是临时实例),所以这里会通过grpc对应类型来进行服务注册,可以看到先构建了服务注册请求实例InstanceRequest
,然后去向注册中心请求,具体的请求我们就不看了。
下面我们看下在微服务中,服务是如何自动注册出的,其实我们可以猜测一下,应该是微服务启动过程中,发布了某一个事件,事件监听器监听到该事件后,就开始调用服务注册代码进行注册工作。
Nacos自动装配
<!-- 文中使用的阿里巴巴服务发现版本 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.5.RELEASE</version> </dependency>
我们先找到自动装配的核心类NacosServiceRegistryAutoConfiguration
点进去发现NacosServiceRegistryAutoConfiguration
里面注入了三个Bean,分别为NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration
服务注册
NacosServiceRegistry
该类实现了具体的注册逻辑,后面我们可以看到,大家先记住它,还有NacosAutoServiceRegistration
也很重要,该类可以说是服务启动后,触发服务注册的入口,我们先看下它的类图
通过类图我们发现该类继承了AbstractAutoServiceRegistration
而父类又实现了ApplicationListener
接口,所以它是个监听类,作为监听类肯定有监听方法,监听方法应该就是我们服务注册的入口,事件监听方法存在父类AbstractAutoServiceRegistration`中
WebServerInitializedEvent该事件在容器完成刷新工作后发布的,具体方法为ServletWebServerApplicationContext#finishRefresh
通过方法参数我们知道监听事件为WebServerInitializedEvent
,字面意思是web服务初始化后事件,而且可以看到监听方法中还调用用bind
方法,bind
方法调用的是start
方法。我们看下start
的具体逻辑
该方法中,终于能看到注册相关的代码了,通过断点我们能看到确实走这里的代码了,我们看下该方法能不能找到我们前面说的测试类中的服务注册相关代码,经过一些方法链调用,最终会调到NacosServiceRegistry#register
方法中,该类也是我们之前自动装配类中添的,我让大家记住的那个类,该方法中我们能看到之前Nacos官方提供的注册中心客户端注册的测试单元方法中具体的注册方法。
文章中阿里巴巴服务发现版本依赖的是nacos-client1.4.1,目前最新的阿里巴巴服务发现版本2021.1依赖的都是nacos-client1.4.1,而官方提供的测试单元中,是用的nacos-client2.0.0的代码,2.0.0加入了grpc的调用,1.4.1这里使用的是http来调用的,NacosServiceRegistry#register点进去看到的和我们上面的代码不一样。不要等下看到代码不一样,都不知道咋回事。
到此微服务中接口Nacos作为服务注册中心就说完了,下面我们看服务端的接收服务注册具体是咋实现的。
服务端
服务注册
服务端注册处理方法其实挺好找的,毕竟有相关handler InstanceRequestHandler
,该handler 包含了服务注册、服务注销,我们服务注册的方法为InstanceRequestHandler#handle
,我们先看下该方法代码:
通过请求参数先生成了Service对象,然后根据类型看走服务注册还是服务注销。
Service
实例它重写了equase和hashcode
方法,通过namespace、group、name
来确定唯一实例,临时实例的注册表保存在内存中,该ConcurrentMap就是服务的注册表,以service来作为key,多个clientId来作为value,这也是为啥Service必须要重写equase和hashcode方法的原因// 服务注册表 ConcurrentMap<Service, Set<String>> publisherIndexes = new ConcurrentHashMap<>()
我们继续看下面的方法逻辑
该方法中主要做了以下事情:
- 通过
ServiceManager
和service获取了一个Service,实际上这里是为了确保service的单例,防止同一namespace、group、name
相同的生成多个Service实例,毕竟Service实例在注册表中是以key存在的,必须唯一
-
通过clientId获取了
Client对象(IpPortBasedClient)
,该client对象在进入InstanceRequestHandler#handle
方法前就已经加入到clientManager
中的,不信可以在ConnectionBasedClientManager#clientConnected
方法入口处打个断点,就可以知道。 -
将客户端注册实例信息转换成服务端注册信息,然后将
Service
和注册实例信息添加到Client中,最后再更新客户端的心跳时间 -
发布服务注册事件
ClientRegisterServiceEvent
和实例元数据事件
服务注册事件处理过程中,会将服务的注册信息注册到注册中心的注册表中,也就是我们上面说的那个ConcurrentMap
,我们看下该事件的监听位置和处理逻辑代码
服务注册的监听器方法为:ClientServiceIndexesManager#onEvent
通过以上方法,我们知道事件处理时,将待注册服务想Nacos的注册表中进行了注册工作,然后发布了一个服务变更的事件。
服务变更事件有两个监听方法,一个是通知该服务的所有服务订阅者,还有一个就是通知集群进行数据同步
1.通知订阅者事件:
2.集群同步事件
集群同步
集群同步放单独的文章去讲解。
最后
以上就是灵巧夏天为你收集整理的【源码系列】Nacos服务注册原理源码Nacos服务注册原理源码的全部内容,希望文章能够帮你解决【源码系列】Nacos服务注册原理源码Nacos服务注册原理源码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复