Nacos之NacosWatch源码解读

在网上没找到该类的资料,只好自己解读,然后整理出来供其他有需要的小伙伴阅读。


NacosWatch的实例化

在spring-cloud-starter-alibaba-nacos-discovery-2.2.6.RELEASE.jar下spring.factories里引入了NacosDiscoveryClientConfiguration,
Nacos之NacosWatch源码解读_第1张图片
NacosDiscoveryClientConfiguration里实例化了NacosWatch,
Nacos之NacosWatch源码解读_第2张图片


NacosWatch的start()调用时机

因为NacosWatch实现了SmartLifecycle接口,所以在启动完Tomcat后会调用start(),

public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {

//...

private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
   Lifecycle bean = lifecycleBeans.remove(beanName);
   if (bean != null && bean != this) {
      String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
      for (String dependency : dependenciesForBean) {
         doStart(lifecycleBeans, dependency, autoStartupOnly);
      }
      if (!bean.isRunning() &&
            (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
         try {
            bean.start(); //NacosWatch
         }
         
   }
   
//...

}

NacosWatch的start()作用

start()是该类的核心方法,也是这篇文章的核心。

public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycle {

	//Map<服务名,监听>
	private Map<String, EventListener> listenerMap = new ConcurrentHashMap<>(16);

    //...

	@Override
	public void start() {
		//CAS锁,以只执行一次
		if (this.running.compareAndSet(false, true)) {
		    //listenerMap里添加注册服务的监听
			EventListener eventListener = listenerMap.computeIfAbsent(buildKey(),
					event -> new EventListener() {
						@Override
						public void onEvent(Event event) {
						    //如果是NamingEvent事件,则选择注册服务的第一个实例,更新metadata
							if (event instanceof NamingEvent) {
								List<Instance> instances = ((NamingEvent) event)
										.getInstances();
								Optional<Instance> instanceOptional = selectCurrentInstance(
										instances);
								instanceOptional.ifPresent(currentInstance -> {
									resetIfNeeded(currentInstance);
								});
							}
						}
					});

			//反射实例化NamingService ,这里是NacosNamingService
			NamingService namingService = nacosServiceManager
					.getNamingService(properties.getNacosProperties());
			try {
			    /**
			     * 1.向InstancesChangeNotifier通知里订阅该服务的实例改变的通知
			     * 2.向nacos服务端发起一次/v1/ns/instance/list的HTTP请求,获取注册服务的列表
			     * 3.开启定时任务更新注册服务的实例列表
			     */
				namingService.subscribe(properties.getService(), properties.getGroup(),
						Arrays.asList(properties.getClusterName()), eventListener);
			}
			catch (Exception e) {
				log.error("namingService subscribe failed, properties:{}", properties, e);
			}

			//延迟30s,且每隔30s向nacos服务端发布一个心跳事件
			this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(
					this::nacosServicesWatch, this.properties.getWatchDelay());
		}
	}

	//...

}


你可能感兴趣的:(nacos,SpringCloud,spring,cloud,spring,cloud,alibaba)