前言

Nacos作为SpringCloud Alibaba微服务生态核心组件之一,它承担着注册与发现、服务配置的作用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。本章将从源码角度探索Nacos是如何实现服务注册的。

Nacos Client

首先从客户端开始,通常我们的服务需要导入spring-cloud-starter-alibaba-nacos-discovery包来帮助我们将当前服务注册到nacos服务端。那么nacos client是何时将我们的服务注册到服务端的呢?在org.springframework.cloud.client.serviceregistry包下的接口ServiceRegistry定义了sprngcloud中服务注册的规范,我们常用的例如eureka、nacos都是实现了这个接口,基于该标准去实现服务注册的。

nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_spring


点击这个类查看其实现类可以看见nacos的实现类-NacosServiceRegistry,这个类实现了register注册方法。在register中会封装一个Instance实例对象后调用namingService的registerInstance进行注册。

nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_java_02

实例注册

在registerInstance方法中,nacos还会创建一个BeatInfo实例发送给服务端用于检测服务的心跳。BeatReactor内部会维护一个线程每隔一段时间就会发送心跳包,并且还会维护一个线程去监听服务端的回应。如果超过指定时间服务端还是没有回应那就代表服务端可能已经宕机了。

nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_spring_03


创建完心跳包后就开始向服务端进行实例注册了,具体的请求方法就封装在serverProxy.registerService中,registerService方法会将当前服务的po、端口号、服务名等信息作为参数通过服务端的open Api:/nacos/v1/ns/service创建服务。下面这个reqApi方法就是发起网络请求的。

nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_spring cloud_04

注册方法何时被调用?

在上面大致讲解了注册流程,那么注册方法实在何时被调用的呢?在spring-cloud-commons包的spring.factories文件中装配了AutoServiceRegistrationAutoConfiguration类。springboot的自动装配机制会自动的将这个类导入spring容器。

nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_spring_05

.

在这个类中注入了一个接口变量AutoServiceRegistration,nacos客户端就实现了这个接口,所以默认就是注入nacos的NacosAutoServiceRegistration,这个类继承了org.springframework.cloud.client.serviceregistry包下的AbstractAutoServiceRegistration类(这个类实现了AutoServiceRegistration和ApplicationListener),而且刚才我们介绍的实现注册操作的NacosServiceRegistry也作为变量被注入在这个类中。这个类监听了事件WebServerInitializedEvent,springboot在初始化完成的时候会在上有发布WebServerInitializedEvent事件,这个类监听到事件就会调用onApplicationEvent方法。而方法中的bind方法会调用star()方法,而star()方法最终也会调用NacosServiceRegistry的registry方法完成服务注册。

nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_微服务_06


nacos注册中心cp和ap是怎么实现的 nacos 注册中心原理_spring_07

总结

说白了就是SpringCloud的标准就是等springboot完成初始化后发布事件WebServerInitializedEvent,下游监听到事件后最终调用registry方法。nacos就是自己实现了registry方法最终通过nacos的openApi向服务发起注册请求。不难发现其中很多规范springcloud已经定义好了,假如是eureka也差不多类似,也是实现Springcloud的ServiceRegistryh并继承AbstractAutoServiceRegistration