Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案,它是Spring Cloud组件被植入Alibaba元素之后的产物。利用Spring Cloud Alibaba,可以快速搭建微服务架构并完成技术升级。中小企业如果需要快速落地业务中台和技术中台,并向数字化业务转型,那Spring Cloud Alibaba绝对是一个“神器”。
本系列将带着大家一起鸟瞰Spring Cloud Alibaba注册中心,从而熟悉它的注册中心架构及相关原理。
咱们可以试着回忆下,没有Spring Cloud Alibaba之前,我们是如何使用Nacos的?
回忆Nacos的使用方式
好吧,Nacos是一款既支持分布式注册中心和分布式配置中心的神器。Nacos官方提供了很多接入模式,比如Spring Framework、Spring Boot等,但是其底层本质上是依赖Nacos提供的SDK,比如Nacos Client。
如果采用Spring Framework Nacos Client(比如nacos-spring-context),则需要开发人员自己维护NacosNamingServce和NacosConfigService实例对象,也就是说开发人员需要自己依赖Nacos Client做二次开发,成本非常大。
如果采用Spring Boot Nacos Starter组件(比如nacos-discovery-spring-boot-starter),则开发人员可以高效的接入Nacos配置中心,并且可以使用Spring Boot提供的各种Starter组件。
如果纯碎采用Spring Cloud作为基础框架,则不能使用Nacos作为注册中心,好纠结啊。
那么有没有一个框架既可以使用Spring Cloud,又可以使用Spring Boot,还能兼容各种注册中心呢,很高兴的告诉大家,Spring Cloud Alibaba就是这个神器,完美的解决了开发人员微服务架构框架选型的问题,用它就是了。
定义Nacos注册中心的Starter组件
在文章“深度剖析Spring Cloud Alibaba系列——如何兼容Spring Cloud”中已经提到过,Spring Cloud Alibaba定义了一个Starter组件spring-cloud-starter-alibaba-nacos-discovery,并利用一个注解@EnableDiscoveryClient就将Spring Cloud Alibaba和Spring Cloud衔接在一起,那么我们这篇再看看它是如何和Nacos衔接在一起的。
废话先不多说了,可以先看相关技术细节,毕竟大家都是程序员,而且还是35岁的程序员。
Spring Cloud Alibaba通过条件注解控制了NacosRegistration类和NacosAutoServiceRegistration类的初始化,那么我们就可以先看看它们的逻辑。
第一步,我们可以看看NacosRegistration类做了哪些事情,哇,我看到了一个注解@PostConstruct,是不是感觉非常的清切,部分核心如下:
代码语言:javascript复制//①省略大部分代码的35岁的程序员
public class NacosRegistration implements Registration, ServiceInstance {
...
@PostConstruct
public void init() {
//②加载服务中,通过属性文件自定义的元数据,并Push到Nacos注册中心,这样在Nacos控制台就能看到开发人员自定义的元数据,这个功能真的非常重要
Map<String, String> metadata = nacosDiscoveryProperties.getMetadata();
//③读取服务中,通过代码硬编码的元数据,并Push到Nacos注册中心
customize(registrationCustomizers, this);
}
//④执行加载元数据的具体逻辑
private static void customize(
List<NacosRegistrationCustomizer> registrationCustomizers,
NacosRegistration registration) {
//⑤其实这里有一个基于Spring Boot和面向接口的设计模式,非常方便大家在业务中做代码扩展,特别是复杂业务设计的场景,读者可以自己先体会。
if (registrationCustomizers != null) {
for (NacosRegistrationCustomizer customizer : registrationCustomizers) {
customizer.customize(registration);
}
}
}
...
}
第二步,我们在看看NacosAutoServiceRegistration类,从类的命名可以看出,这个肯定是与服务注册相关的了。
看到一堆代码,估计很多人觉得很繁琐,会觉得真没意思,天天撸代码,还要去看人家的代码,但是你要想想你可是35岁的程序员呢。
首先我们看看如下代码,哈哈看代码吧,看到了AbstractAutoServiceRegistration类,它是Spring Cloud注册中心的核心类,如下:
代码语言:javascript复制public class NacosAutoServiceRegistration
extends AbstractAutoServiceRegistration<Registration> {
private NacosRegistration registration;
//①好吧,Spring cloud Alibaba重写了Spring Cloud的注册方法register()
@Override
protected void register() {
//②如果开启了自动注册,则调用Spring Cloud的注册方法,开启服务Spring Cloud的服务注册
if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
log.debug("Registration disabled.");
return;
}
if (this.registration.getPort() < 0) {
this.registration.setPort(getPort().get());
}
super.register();
}
...
}
好吧看到这里,是不是感觉和Nacos没有关系呢,我们可以先不着急,慢慢看,慢慢分析。
其次,我们再看看NacosServiceRegistry类,这个就是一个非常关键的类,废话不说,我们看看它是在哪初始化的呢?如下:
代码语言:javascript复制@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 {
//没错,它就是在NacosServiceRegistryAutoConfiguration 类中初始化的,但是这个Bean的初始化是没有靠条件注解来控制,个人感觉这里就应该加一个,读者可以自己尝试下,引入Spring Cloud Alibaba的包,但是不加注解@EnableDiscoveryClient,服务是会报错的。
@Bean
public NacosServiceRegistry nacosServiceRegistry(
NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosServiceRegistry(nacosDiscoveryProperties);
}
...
}
然后我们再看看NacosServiceRegistry 类做了哪些事情,如下:
代码语言:javascript复制public class NacosServiceRegistry implements ServiceRegistry<Registration> {
//①NacosServiceManager 是Spring Cloud Alibaba对Nacos Client的二次封装
@Autowired
private NacosServiceManager nacosServiceManager;
//②好吧,看到NamingService 类是不是很兴奋,没错,用它就是来注册服务的
@Override
public void register(Registration registration) {
NamingService namingService = namingService();
Instance instance = getNacosInstanceFromRegistration(registration);
namingService.registerInstance(serviceId, group, instance);
...
}
@Override
//③好吧,看到NamingService 类是不是很兴奋,没错,用它就是来取消注册服务的
public void deregister(Registration registration) {
NamingService namingService = namingService();
namingService.deregisterInstance(serviceId, group, registration.getHost(),
registration.getPort(), nacosDiscoveryProperties.getClusterName());
...
}
...
}
我好像有点懂了,但是感觉还是比较模棱两可,好吧,我们再来回忆一下Spring Cloud完成服务注册的原理:Spring Cloud采用@EnableDiscoveryClient 对应注册中心的Starter组件完成服务的注册,也就是说它底层有它自身的一套标准的注册的流程,服务注册的元数据已经标准化,所以NacosServiceRegistry 类就是Spring Cloud Alibaba用来将Spring Cloud服务注册的元数据转换为Nacos支持的元数据,这样才能完成服务的注册。
好吧,通过这样的解释,是不是已经有点懂了,如果不懂可以参考图书“Spring Cloud Alibaba微服务架构实战派(上下册)”。
总结
本文带着大家一起看了Spring Cloud Alibaba是如何衔接Spring Cloud和Nacos的部分原理,读者如果感兴趣可以自行查阅一下相关源码。
下一期:继续剖析