文章目录
服务注册入口
无论是将服务注册到哪种服务注册中心,服务注册的时机都是在AbstractApplicationContext#finishRefresh()方法中;即Spring容器加载完成、Web服务启动之后;
从SpringCloud规范来看,Spring-cloud-common包定义了一套服务注册、发现的规范;服务注册逻辑在ServiceRegistry类中;
packageorg.springframework.cloud.client.serviceregistry;/**
* Contract to register and deregister instances with a Service Registry.
*
* @param <R> registration meta data
* @author Spencer Gibb
* @since 1.2.0
*/publicinterfaceServiceRegistry<RextendsRegistration>{/**
* Registers the registration. A registration typically has information about an
* instance, such as its hostname and port.
* @param registration registration meta data
*/voidregister(R registration);/**
* Deregisters the registration.
* @param registration registration meta data
*/voidderegister(R registration);/**
* Closes the ServiceRegistry. This is a lifecycle method.
*/voidclose();/**
* Sets the status of the registration. The status values are determined by the
* individual implementations.
* @param registration The registration to update.
* @param status The status to set.
* @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint
*/voidsetStatus(R registration,String status);/**
* Gets the status of a particular registration.
* @param registration The registration to query.
* @param <T> The type of the status.
* @return The status of the registration.
* @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint
*/<T>TgetStatus(R registration);}
1、Eureka
从SpringBoot自动装配来看,
spring-cloud-netflix-eureka-client
包中有一个自动装配类
EurekaClientAutoConfiguration
;
其中使用@Bean注入一个类
EurekaAutoServiceRegistration
,它实现了SmartLifecycle接口
当Spring容器初始化完成之后会执行所有SmartLifecycle#start()方法,链路如下:
进而走到EurekaAutoServiceRegistration#start()方法中;
其中的
serviceRegistry.register()
负责服务注册到服务注册中⼼Eureka。Eureka中
EurekaServiceRegistry
类实现了
ServiceRegistry
接口,因此Eureka服务注册的入口为EurekaServiceRegistry#register()方法;
@Overridepublicvoidregister(EurekaRegistration reg){maybeInitializeClient(reg);if(log.isInfoEnabled()){
log.info("Registering application "+ reg.getApplicationInfoManager().getInfo().getAppName()+" with eureka with status "+ reg.getInstanceConfig().getInitialStatus());}
reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus());
reg.getHealthCheckHandler().ifAvailable(healthCheckHandler -> reg
.getEurekaClient().registerHealthCheck(healthCheckHandler));}
2、Nacos
从SpringBoot自动装配来看,
spring-cloud-alibaba-nacos-discovery
包中有一个自动装配类
NacosServiceRegistryAutoConfiguration
;NacosServiceRegistryAutoConfiguration中会使用
@Bean
注解装配
NacosAutoServiceRegistration
类;
publicclassNacosServiceRegistryAutoConfiguration{@BeanpublicNacosServiceRegistrynacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties){returnnewNacosServiceRegistry(nacosDiscoveryProperties);}@Bean@ConditionalOnBean(AutoServiceRegistrationProperties.class)publicNacosAutoServiceRegistrationnacosAutoServiceRegistration(NacosServiceRegistry registry,AutoServiceRegistrationProperties autoServiceRegistrationProperties,NacosRegistration registration){returnnewNacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);}....}
NacosAutoServiceRegistration
间接实现了
ApplicationListener
接⼝;
其会监听Web服务初始化完成事件
WebServerInitializedEvent
;
在Spring生命周期中,上下文刷新完成阶段,即finishRefresh()方法中会执行所有SmartLifecycle#start()方法;
WebServerStartStopLifecycle实现了SmartLifecycle接口,进而走到WebServerStartStopLifecycle#start()方法,其中会发布Servlet服务初始化完成事件
ServletWebServerInitializedEvent
。
ServletWebServerInitializedEvent是WebServerInitializedEvent的子类。所以监听WebServerInitializedEvent的ApplicationListener可以监听到ServletWebServerInitializedEvent。
NacosAutoServiceRegistration的父类AbstractAutoServiceRegistration中基于ApplicationListener#onApplicationEvent()监听到事件;
然后走到NacosAutoServiceRegistration#register()方法开始做服务注册;
最终会走到
ServiceRegistry
接口的
register(R registration)
⽅法将服务注册到注册中⼼。Nacos中
NacosServiceRegistry
类实现了
ServiceRegistry
接口。
总结
从Eureka和Nacos做服务注册的入口来看,有两种方式让我们去做服务注册。
- 基于扩展SmartLifecycle接口实现,在Spring上下文刷新完毕之后会执行SmartLifecycle#start()方法;
- 基于监听Spring事件WebServerInitializedEvent,在ApplicationListener#onApplicationContext()方法中写逻辑; 基于Spring事件机制的特性,可以做异步服务注册处理。本质上也是利用了SmartLifecycle接口,区别在于使用了SpringBoot web模块的WebServerStartStopLifecycle。
此外,还要遵循spring-cloud-common定义的规范,自定义服务注册的入口类一定要是
ServiceRegistry
接口的实现类。
版权归原作者 秃秃爱健身 所有, 如有侵权,请联系我们删除。