后面文章咱们介绍了Nacos的性能及设计架构,这篇文章就以Nacos提供的服务注册性能为主线,来解说Nacos的客户端是如何在Spring Cloud进行集成和实现的。

本会配合源码剖析、流程图整顿、外围API解析等维度来让大家深入浅出、零碎的来学习。

Spring Boot的主动注册

故事要从头Spring Boot的主动注入开始。很多敌人大略都理解过Spring Boot的主动配置性能,而Spring Cloud又是基于Spring Boot框架的。

因而,在学习Nacos注册业务之前,咱们先来回顾一下Spring Boot的主动配置原理,这也是学习的入口。

Spring Boot通过@EnableAutoConfiguration注解,将所有符合条件的@Configuration配置都加载到以后SpringBoot创立并应用的IoC容器。

上述过程是通过@Import(AutoConfigurationImportSelector.class)导入的配置性能,AutoConfigurationImportSelector中的办法getCandidateConfigurations,失去待配置的class的类名汇合,即所有须要进行主动配置的(xxxAutoConfiguration)类,这些类配置于META-INF/spring.factories文件中。

最初,依据这些全限定名类上的注解,如:OnClassCondition、OnBeanCondition、OnWebApplicationCondition条件化的决定要不要主动配置。

理解了Spring Boot的根本配置之后,咱们来看看Nacos对应的主动配置在哪里。

Spring Cloud中的Nacos主动配置

查看Spring Cloud的我的项目依赖,自己引入依赖对应的jar包为spring-cloud-starter-alibaba-nacos-discovery-2021.1.jar;

对应的pom依赖为:

<dependency>    <groupId>com.alibaba.cloud</groupId>    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

查看jar包中META-INF/spring.factories文件的内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\  com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\  com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\  com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\  com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\  com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\  com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,\  com.alibaba.cloud.nacos.NacosServiceAutoConfigurationorg.springframework.cloud.bootstrap.BootstrapConfiguration=\  com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration

能够看到EnableAutoConfiguration类对应了一系列的Nacos主动配置类。

其中NacosServiceRegistryAutoConfiguration是用来封装实例化Nacos注册流程所需组件的,装载了对三个对象NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration,这三个对象整体都是为了Nacos服务注册应用的。

@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties@ConditionalOnNacosDiscoveryEnabled@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",        matchIfMissing = true)@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,        AutoServiceRegistrationAutoConfiguration.class,        NacosDiscoveryAutoConfiguration.class })public class NacosServiceRegistryAutoConfiguration {    @Bean    public NacosServiceRegistry nacosServiceRegistry(            NacosDiscoveryProperties nacosDiscoveryProperties) {        return new NacosServiceRegistry(nacosDiscoveryProperties);    }    @Bean    @ConditionalOnBean(AutoServiceRegistrationProperties.class)    public NacosRegistration nacosRegistration(            ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers,            NacosDiscoveryProperties nacosDiscoveryProperties,            ApplicationContext context) {        return new NacosRegistration(registrationCustomizers.getIfAvailable(),                nacosDiscoveryProperties, context);    }    @Bean    @ConditionalOnBean(AutoServiceRegistrationProperties.class)    public NacosAutoServiceRegistration nacosAutoServiceRegistration(            NacosServiceRegistry registry,            AutoServiceRegistrationProperties autoServiceRegistrationProperties,            NacosRegistration registration) {        return new NacosAutoServiceRegistration(registry,                autoServiceRegistrationProperties, registration);    }}

其中NacosServiceRegistry封装的就是注册流程,它继承自ServiceRegistry:

public class NacosServiceRegistry implements ServiceRegistry<Registration> {...}

查看该类源码,能够看到该类中实现了服务注册、登记、敞开、设置状态、获取状态5个性能。

咱们要追踪的服务注册性能,便是通过它提供的register办法来实现的。

至此,咱们能够梳理一下Nacos客户端在Spring Cloud中集成并实例化的解决流程。

Spring Cloud的ServiceRegistry接口

下面提到NacosServiceRegistry集成自ServiceRegistry,那么ServiceRegistry又是何方神圣呢?

ServiceRegistry接口是Spring Cloud的类,来看一下ServiceRegistry接口的定义:

public interface ServiceRegistry<R extends Registration> {    void register(R registration);    void deregister(R registration);    void close();    void setStatus(R registration, String status);    <T> T getStatus(R registration);}

能够看出ServiceRegistry接口中定义了服务注册、登记、敞开、设置状态、获取状态五个接口。

如果看其余服务发现框架对Spring Cloud进行集成时,基本上都是实现的这个接口。也就是说,ServiceRegistry是Spring Cloud提供的一个服务发现框架集成的标准。对应的框架装置标准实现对应的性能即可进行集成。

咱们能够看到Eureka、Zookeeper、Consul在Spring Cloud中集成也都是实现了该接口,同时,如果你须要自定义服务发现性能,也能够通过实现该接口来达到目标。

NacosServiceRegistry服务注册实现

暂且不关注其余的辅助类,间接来看NacosServiceRegistry#register办法,它提供了服务注册的外围业务逻辑实现。

咱们把该类的辅助判断去掉,间接展现最外围的代码如下:

@Overridepublic void register(Registration registration) {    // 获取NamingService    NamingService namingService = namingService();    String serviceId = registration.getServiceId();    String group = nacosDiscoveryProperties.getGroup();    // 结构实例,封装信息来源于配置属性    Instance instance = getNacosInstanceFromRegistration(registration);    // 将实例进行注册    namingService.registerInstance(serviceId, group, instance);}

上述代码中NamingService曾经属于Nacos Client我的项目提供的API反对了。

对于Nacos Client的API流程查看,可间接查看Nacos对应的源码,NamingService#registerInstance办法对应的流程图整顿如下:

上述流程图还能够持续细化,这个咱们在后续章节中进行专门解说,这里大家晓得大略的调用流程即可。

Spring Cloud服务注册链路

上面咱们来梳理一下Spring Cloud是如何进行服务注册的,其中流程的前三分之二局部简直所有的服务注册框架都是一样的流程,只有最初一部分进行实例注册时会调用具体的框架来进行实现。

间接来看整个调用的链路图:

图中不同的色彩代表这不同的框架,灰色示意业务代码,浅绿色示意SpringBoot框架,深绿色示意Spring框架,浅橙色示意SpringCloud框架,其中这一部分也蕴含了依赖的Nacos组件局部,最初浅紫色代表着Nacos Client的包。

外围流程分以下几步:

第一步,SpringBoot在启动main办法时调用到Spring的外围办法refresh;

第二步,在Spring中实例化了WebServerStartStopLifecycle对象。

重点说一下WebServerStartStopLifecycle对象,它的start办法被调用时会公布一个ServletWebServerInitializedEvent事件类,这个事件类继承自WebServerInitializedEvent。前面用来解决服务注册的类AbstractAutoServiceRegistration同时也是一个监听器,专门用来监听WebServerInitializedEvent事件。

第三步,AbstractApplicationContext的finishRefresh中会间接调用DefaultLifecycleProcessor的startBeans办法,进而调用了WebServerStartStopLifecycle的start办法。就像下面说的,触发了ServletWebServerInitializedEvent事件的公布。

第四步,AbstractAutoServiceRegistration监听到对应的事件,而后基于Spring Cloud定义的ServiceRegistry接口进行服务注册。

下面的形容省略了一些局部细节,但整个流程基本上就是SpringBoot在启动时公布了一个事件,Spring Cloud监听到对应的事件,而后进行服务的注册。

小结

为了这篇文章,肝了好几天。Spring Cloud源码、Spring Boot源码、Nacos源码都翻了个遍。最终为大家分享了Nacos或者说是Spring Cloud中服务发现的实现机制及流程。

之所以写这篇文章,也是想提倡大家更多的走进源码,而不是仅仅在应用。你学到了吗?

PS:笔者打算在较长一段时间内钻研Spring Cloud微服务系列源码,像这篇文章一样深刻底层源码。Nacos(服务发现)只是开设,如果你对此方面感兴趣,增加微信好友,备注Nacos,在人数足够时会建设相干交换群。