后面文章咱们介绍了 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.NacosServiceAutoConfiguration
org.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 办法,它提供了服务注册的外围业务逻辑实现。
咱们把该类的辅助判断去掉,间接展现最外围的代码如下:
@Override
public 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,在人数足够时会建设相干交换群。