我是靠谱客的博主 积极蜡烛,最近开发中收集的这篇文章主要介绍Nacos 服务注册注销源码浅析入口NacosAutoServiceRegistrationAbstractAutoServiceRegistration总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

从引入的 Nacos Discovery 的 starter 中找 spring.factories 文件,咱们能看到下图,既然是了解服务注册的,按照 Spring Boot 的习俗,咱们应该重点关注红框中的内容 NacosServiceRegistryAutoConfiguration
在这里插入图片描述

入口

从上面咱们知道了入口是 NacosServiceRegistryAutoConfiguration,点进去看下:

@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(
			NacosServiceManager nacosServiceManager,
			NacosDiscoveryProperties nacosDiscoveryProperties) {
		return new NacosServiceRegistry(nacosServiceManager, 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);
	}

}

@ConditionalOnXxxYyy 注解是一些条件注解,这里不再赘述,@AutoConfigureAfter 代表加载了制定的类之后再加载当前类。

NacosAutoServiceRegistration

public class NacosAutoServiceRegistration
		extends AbstractAutoServiceRegistration<Registration> {

	private static final Logger log = LoggerFactory
			.getLogger(NacosAutoServiceRegistration.class);

	private NacosRegistration registration;

	public NacosAutoServiceRegistration(ServiceRegistry<Registration> serviceRegistry,
			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
			NacosRegistration registration) {
		super(serviceRegistry, autoServiceRegistrationProperties);
		this.registration = registration;
	}
	// 省略部分代码

}

先看下类图,我们会发现通过继承实现了 ApplicationListener 接口的抽象类 AbstractAutoServiceRegistration 获得了以下能力:

	public void onApplicationEvent(WebServerInitializedEvent event) {
		bind(event);
	}

在这里插入图片描述

AbstractAutoServiceRegistration

注册

AbstractAutoServiceRegistration#bind(WebServerInitializedEvent event)

	@Deprecated
	public void bind(WebServerInitializedEvent event) {
		ApplicationContext context = event.getApplicationContext();
		if (context instanceof ConfigurableWebServerApplicationContext) {
			if ("management".equals(((ConfigurableWebServerApplicationContext) context)
					.getServerNamespace())) {
				return;
			}
		}
		this.port.compareAndSet(0, event.getWebServer().getPort());]
		// 直接看 start() 方法
		this.start();
	}

AbstractAutoServiceRegistration#start()

	public void start() {
		if (!isEnabled()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Discovery Lifecycle disabled. Not starting");
			}
			return;
		}

		// only initialize if nonSecurePort is greater than 0 and it isn't already running
		// because of containerPortInitializer below
		if (!this.running.get()) {
			// 发布预注册事件
			this.context.publishEvent(
					new InstancePreRegisteredEvent(this, getRegistration()));
			register();
			if (shouldRegisterManagement()) {
				registerManagement();
			}
			// 发布注册事件
			this.context.publishEvent(
					new InstanceRegisteredEvent<>(this, getConfiguration()));
			this.running.compareAndSet(false, true);
		}

	}

其中 register()registerManagement() 都会调用到 ServiceRegistry#register(R registration)

NacosServiceRegistry

NacosServiceRegistry 是 ServiceRegistry 的一个实现。

	@Override
	public void register(Registration registration) {

		if (StringUtils.isEmpty(registration.getServiceId())) {
			log.warn("No service to register for nacos client...");
			return;
		}

		NamingService namingService = namingService();
		String serviceId = registration.getServiceId();
		String group = nacosDiscoveryProperties.getGroup();
		// 获取实例
		Instance instance = getNacosInstanceFromRegistration(registration);

		try {
			// 注册实例
			namingService.registerInstance(serviceId, group, instance);
			log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
					instance.getIp(), instance.getPort());
		}
		catch (Exception e) {
			if (nacosDiscoveryProperties.isFailFast()) {
				log.error("nacos registry, {} register failed...{},", serviceId,
						registration.toString(), e);
				rethrowRuntimeException(e);
			}
			else {
				log.warn("Failfast is false. {} register failed...{},", serviceId,
						registration.toString(), e);
			}
		}
	}

NacosNamingService

public class NacosNamingService implements NamingService {

	// 省略代码
	
    private NamingClientProxy clientProxy;
    
    @Override
    public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
        NamingUtils.checkInstanceIsLegal(instance);
        clientProxy.registerService(serviceName, groupName, instance);
    }

看到最终是通过 clientProxy.registerService(serviceName, groupName, instance); 完成了实例的注册。

注销

回到 AbstractAutoServiceRegistration 类中,我们看到了被 @PreDestroy 标注的方法,含义是在应用程序关闭时执行被 @PreDestroy 标注的方法:

	@PreDestroy
	public void destroy() {
		stop();
	}

AbstractAutoServiceRegistration#stop()

	public void stop() {
		if (this.getRunning().compareAndSet(true, false) && isEnabled()) {
			deregister();
			if (shouldRegisterManagement()) {
				deregisterManagement();
			}
			this.serviceRegistry.close();
		}
	}

其中 deregister() 以及 deregisterManagement() 都会执行 serviceRegistry.deregister(registration),进行服务的注销。

NacosServiceRegistry#deregister(Registration registration)

上文说到的 serviceRegistry 在 Nacos 中的实现是 NacosServiceRegistry,看下具体的方法:

@Override
	public void deregister(Registration registration) {

		log.info("De-registering from Nacos Server now...");

		if (StringUtils.isEmpty(registration.getServiceId())) {
			log.warn("No dom to de-register for nacos client...");
			return;
		}

		NamingService namingService = namingService();
		String serviceId = registration.getServiceId();
		String group = nacosDiscoveryProperties.getGroup();

		try {
			namingService.deregisterInstance(serviceId, group, registration.getHost(),
					registration.getPort(), nacosDiscoveryProperties.getClusterName());
		}
		catch (Exception e) {
			log.error("ERR_NACOS_DEREGISTER, de-register failed...{},",
					registration.toString(), e);
		}

		log.info("De-registration finished.");
	}

namingService.deregisterInstance(serviceId, group, registration.getHost(), registration.getPort(), nacosDiscoveryProperties.getClusterName()); 交由 NacosNamingService 完成

NacosNamingService#deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName)

    @Override
    public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName)
            throws NacosException {
        Instance instance = new Instance();
        instance.setIp(ip);
        instance.setPort(port);
        instance.setClusterName(clusterName);
       	// 注销实例
        deregisterInstance(serviceName, groupName, instance);
    }

NacosNamingService#deregisterInstance(String serviceName, String groupName, Instance instance)

    @Override
    public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
        clientProxy.deregisterService(serviceName, groupName, instance);
    }

其实在上面能看到最终是通过 clientProxy.deregisterService(serviceName, groupName, instance); 完成了服务的注销。

总结

Nacos 通过监听事件完成服务的注册,通过 @PreDestroy 标注的方法完成服务的注销。

剧透下:

  1. NamingClientProxy 有两种,分别是 NamingHttpClientProxy 以及 NamingGrpcClientProxy,选择哪个进行注册通过 NamingClientProxyDelegate 做了委托(下图的一个判断)。临时实例走 grpc,持久化实例走 httpclient。
    在这里插入图片描述
  2. NamingHttpClientProxy 会执行向 Nacos Server 端发送 HTTP 请求的方式注册和注销。

最后

以上就是积极蜡烛为你收集整理的Nacos 服务注册注销源码浅析入口NacosAutoServiceRegistrationAbstractAutoServiceRegistration总结的全部内容,希望文章能够帮你解决Nacos 服务注册注销源码浅析入口NacosAutoServiceRegistrationAbstractAutoServiceRegistration总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部