前言
分析springboot与nacos的整合,其中包括注册中心与配置中心的分析。springboot版本:2.4.13,spring-cloud-alibaba:2021.1
一、整合机制
通过spring提供的自动装配机制,扫描spring.factories文件。以下分别是nacos-discovery(注册中心)跟nacos-config(配置中心)中的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
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer
org.springframework.boot.env.PropertySourceLoader=\
com.alibaba.cloud.nacos.parser.NacosJsonPropertySourceLoader,\
com.alibaba.cloud.nacos.parser.NacosXmlPropertySourceLoader
后面几章将分别对其进行分析。
二、注册中心
1、服务注册
1.1、概述
服务注册的功能是将我们的服务是注册到nacos上,以便其他服务可以使用该服务。
1.2、流程分析
根据上面的spring.factories文件,我们看到里面有个根注册registry有关的类NacosServiceRegistryAutoConfiguration【1】,代码如下:
@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 {
public 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((List)registrationCustomizers.getIfAvailable(), nacosDiscoveryProperties, context);
}
@Bean
@ConditionalOnBean({AutoServiceRegistrationProperties.class})
public NacosAutoServiceRegistration nacosAutoServiceRegistration(NacosServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);
}
}
代码比较少,我们重点关注两点,第一,可以看到这个配置类生效的条件:spring.cloud.service-registry.auto-registration.enabled,所以服务注册是通过这个配置来开启的,并且默认是true;第二,这里面注入了两个类NacosServiceRegistry【2】跟NacosAutoServiceRegistration【3】,我们通过分析NacosAutoServiceRegistration得到下图逻辑:
2、心跳机制
2.1、概述
服务定时主动向nacos发送心跳请求,维护服务的健康状态。
2.2、流程分析
在上面已经有过截图,NacosNamingService::registerInstance方法中已经发送了心跳了,通过调用BeatReactor的addBeatInfo方法,在里面通过ScheduledThreadPoolExecutor不断的去发送心跳请求。(注意executorService调用的是schedule方法,而不是scheduleAtFixedRate或者scheduleWithFixedDelay,里面的作用需要自己去体会,我觉得设计得还挺巧妙的)
3、服务发现
3.1、概述
同一个nacos的注册中心中注册了很多服务,当前服务是如何发现这些服务的。
3.2、流程分析
假设当前nacos中注册了3个服务:
订单服务order-serve
库存服务stock-serve
积分服务points-serve
以订单服务为例(当前服务):在订单服务启动后,会通过NacosDiscoveryClientConfiguration【1】注入NacosWatch【2】,这里面会去根据当前服务名拿当前服务的所有实例,这时并没有把3个服务的实例全部拿下来, 而是仅仅只拿了当前服务的服务实例。那么库存服务、积分服务的实例什么时候去从nacos中拿呢?答案是:在这些服务被真正调用过后(比如进行了OpenFeign或者其他的调用后,OpenFeign的调用流程后面分析)。下面是服务拉取的流程分析图:
里面跟心跳维护的机制一样,定时调用http接口。会针对每个服务名进行一个定时任务的维护futureMap<服务名称,ScheduleFuture>,在HostReactor.UpdateTask【3】里面根据服务名称定时拉取服务实例信息;其他服务在被调用时,也会被加到这个定时任务集合中。对拉取的实例会缓存到一个Map中(Map<String, ServiceInfo> serviceInfoMap)。