diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java index af722dda2..b1021eef7 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java @@ -20,6 +20,7 @@ import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.NacosServiceManager; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -31,6 +32,7 @@ import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.TaskScheduler; /** * @author xiaojing @@ -56,8 +58,10 @@ public class NacosDiscoveryClientConfiguration { @ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", matchIfMissing = true) public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager, - NacosDiscoveryProperties nacosDiscoveryProperties) { - return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties); + NacosDiscoveryProperties nacosDiscoveryProperties, + ObjectProvider taskExecutorObjectProvider) { + return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties, + taskExecutorObjectProvider); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java index 7d5d1858a..a58f46124 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java @@ -54,7 +54,8 @@ public class NacosServiceDiscovery { */ public List getInstances(String serviceId) throws NacosException { String group = discoveryProperties.getGroup(); - List instances = namingService().selectInstances(serviceId, group, true); + List instances = namingService().selectInstances(serviceId, group, + true); return hostToServiceInstanceList(instances, serviceId); } @@ -111,7 +112,8 @@ public class NacosServiceDiscovery { } private NamingService namingService() { - return nacosServiceManager.getNamingService(discoveryProperties.getNacosProperties()); + return nacosServiceManager + .getNamingService(discoveryProperties.getNacosProperties()); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java index ff9040ae7..4a78238f9 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -35,10 +36,13 @@ import com.alibaba.nacos.api.naming.pojo.Instance; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.client.discovery.event.HeartbeatEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.SmartLifecycle; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** * @author xiaojing @@ -56,14 +60,27 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl private ApplicationEventPublisher publisher; + private ScheduledFuture watchFuture; + private NacosServiceManager nacosServiceManager; private final NacosDiscoveryProperties properties; + private final TaskScheduler taskScheduler; + public NacosWatch(NacosServiceManager nacosServiceManager, - NacosDiscoveryProperties properties) { + NacosDiscoveryProperties properties, + ObjectProvider taskScheduler) { this.nacosServiceManager = nacosServiceManager; this.properties = properties; + this.taskScheduler = taskScheduler.getIfAvailable(NacosWatch::getTaskScheduler); + } + + private static ThreadPoolTaskScheduler getTaskScheduler() { + ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setBeanName("Nacos-Watch-Task-Scheduler"); + taskScheduler.initialize(); + return taskScheduler; } @Override @@ -97,8 +114,6 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl instanceOptional.ifPresent(currentInstance -> { resetIfNeeded(currentInstance); }); - publisher.publishEvent(new HeartbeatEvent(NacosWatch.this, - nacosWatchIndex.getAndIncrement())); } } }); @@ -112,6 +127,9 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl catch (Exception e) { log.error("namingService subscribe failed, properties:{}", properties, e); } + + this.watchFuture = this.taskScheduler.scheduleWithFixedDelay( + this::nacosServicesWatch, this.properties.getWatchDelay()); } } @@ -135,10 +153,17 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl @Override public void stop() { if (this.running.compareAndSet(true, false)) { + if (this.watchFuture != null) { + // shutdown current user-thread, + // then the other daemon-threads will terminate automatic. + ((ThreadPoolTaskScheduler) this.taskScheduler).shutdown(); + this.watchFuture.cancel(true); + } + EventListener eventListener = listenerMap.get(buildKey()); - NamingService namingService = nacosServiceManager - .getNamingService(properties.getNacosProperties()); try { + NamingService namingService = nacosServiceManager + .getNamingService(properties.getNacosProperties()); namingService.unsubscribe(properties.getService(), properties.getGroup(), Arrays.asList(properties.getClusterName()), eventListener); } @@ -159,4 +184,12 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl return 0; } + public void nacosServicesWatch() { + + // nacos doesn't support watch now , publish an event every 30 seconds. + this.publisher.publishEvent( + new HeartbeatEvent(this, nacosWatchIndex.getAndIncrement())); + + } + }