从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机

文章目录

  • 服务注册入口
    • 1、Eureka
    • 2、Nacos
  • 总结

服务注册入口

无论是将服务注册到哪种服务注册中心,服务注册的时机都是在AbstractApplicationContext#finishRefresh()方法中;即Spring容器加载完成、Web服务启动之后;

从SpringCloud规范来看,Spring-cloud-common包定义了一套服务注册、发现的规范;服务注册逻辑在ServiceRegistry类中;

package org.springframework.cloud.client.serviceregistry;

/**
 * Contract to register and deregister instances with a Service Registry.
 *
 * @param  registration meta data
 * @author Spencer Gibb
 * @since 1.2.0
 */
public interface ServiceRegistry<R extends Registration> {

	/**
	 * Registers the registration. A registration typically has information about an
	 * instance, such as its hostname and port.
	 * @param registration registration meta data
	 */
	void register(R registration);

	/**
	 * Deregisters the registration.
	 * @param registration registration meta data
	 */
	void deregister(R registration);

	/**
	 * Closes the ServiceRegistry. This is a lifecycle method.
	 */
	void close();

	/**
	 * 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
	 */
	void setStatus(R registration, String status);

	/**
	 * Gets the status of a particular registration.
	 * @param registration The registration to query.
	 * @param  The type of the status.
	 * @return The status of the registration.
	 * @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint
	 */
	<T> T getStatus(R registration);

}

1、Eureka

从SpringBoot自动装配来看,spring-cloud-netflix-eureka-client包中有一个自动装配类EurekaClientAutoConfiguration

其中使用@Bean注入一个类EurekaAutoServiceRegistration,它实现了SmartLifecycle接口

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第1张图片

当Spring容器初始化完成之后会执行所有SmartLifecycle#start()方法,链路如下:

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第2张图片
从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第3张图片

进而走到EurekaAutoServiceRegistration#start()方法中;

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第4张图片

其中的serviceRegistry.register()负责服务注册到服务注册中⼼Eureka。Eureka中EurekaServiceRegistry类实现了ServiceRegistry接口,因此Eureka服务注册的入口为EurekaServiceRegistry#register()方法;

@Override
public void register(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

public class NacosServiceRegistryAutoConfiguration {

	@Bean
	public NacosServiceRegistry nacosServiceRegistry(
			NacosDiscoveryProperties nacosDiscoveryProperties) {
		return new NacosServiceRegistry(nacosDiscoveryProperties);
	}

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	public NacosAutoServiceRegistration nacosAutoServiceRegistration(
			NacosServiceRegistry registry,
			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
			NacosRegistration registration) {
		return new NacosAutoServiceRegistration(registry,
				autoServiceRegistrationProperties, registration);
	}

    ....
}

NacosAutoServiceRegistration间接实现了ApplicationListener接⼝

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第5张图片
在这里插入图片描述

其会监听Web服务初始化完成事件WebServerInitializedEvent

在Spring生命周期中,上下文刷新完成阶段,即finishRefresh()方法中会执行所有SmartLifecycle#start()方法;

WebServerStartStopLifecycle实现了SmartLifecycle接口,进而走到WebServerStartStopLifecycle#start()方法,其中会发布Servlet服务初始化完成事件ServletWebServerInitializedEvent

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第6张图片

ServletWebServerInitializedEvent是WebServerInitializedEvent的子类。所以监听WebServerInitializedEvent的ApplicationListener可以监听到ServletWebServerInitializedEvent。

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第7张图片

NacosAutoServiceRegistration的父类AbstractAutoServiceRegistration中基于ApplicationListener#onApplicationEvent()监听到事件;

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第8张图片

然后走到NacosAutoServiceRegistration#register()方法开始做服务注册;

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第9张图片

最终会走到ServiceRegistry接口的register(R registration)⽅法将服务注册到注册中⼼。Nacos中NacosServiceRegistry类实现了ServiceRegistry接口。

从SpringBoot生命周期来看服务注册到Eureka/Nacos的时机_第10张图片

总结

从Eureka和Nacos做服务注册的入口来看,有两种方式让我们去做服务注册。

  1. 基于扩展SmartLifecycle接口实现,在Spring上下文刷新完毕之后会执行SmartLifecycle#start()方法;
  2. 基于监听Spring事件WebServerInitializedEvent,在ApplicationListener#onApplicationContext()方法中写逻辑;
    基于Spring事件机制的特性,可以做异步服务注册处理。
    本质上也是利用了SmartLifecycle接口,区别在于使用了SpringBoot web模块的WebServerStartStopLifecycle。

此外,还要遵循spring-cloud-common定义的规范,自定义服务注册的入口类一定要是ServiceRegistry接口的实现类。

你可能感兴趣的:(微服务入门到入土,spring,cloud,服务发现)