diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java index 0882ee08a..52fedfe60 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java @@ -30,6 +30,7 @@ import java.util.regex.Pattern; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingMaintainService; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.PreservedMetadataKeys; @@ -273,10 +274,10 @@ public class NacosDiscoveryProperties { this.namingMaintainService = createMaintainService(properties); } - @PreDestroy - public void destroy() { - - } + @PreDestroy + public void destroy() throws NacosException { + namingService.shutDown(); + } public String getEndpoint() { return endpoint; diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java index 2976e8757..eaf426392 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java @@ -16,6 +16,9 @@ package com.alibaba.cloud.sidecar; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; @@ -28,11 +31,14 @@ import org.springframework.core.env.ConfigurableEnvironment; /** * @author www.itmuch.com + * @author yuhuangbin */ public class SidecarHealthChecker { private static final Logger log = LoggerFactory.getLogger(SidecarHealthChecker.class); + private final Map sidecarInstanceCacheMap = new ConcurrentHashMap<>(); + private final SidecarDiscoveryClient sidecarDiscoveryClient; private final HealthIndicator healthIndicator; @@ -52,26 +58,60 @@ public class SidecarHealthChecker { public void check() { Schedulers.single().schedulePeriodically(() -> { + String applicationName = environment.getProperty("spring.application.name"); String ip = sidecarProperties.getIp(); Integer port = sidecarProperties.getPort(); Status status = healthIndicator.health().getStatus(); - String applicationName = environment.getProperty("spring.application.name"); + instanceCache(applicationName, ip, port, status); if (status.equals(Status.UP)) { - this.sidecarDiscoveryClient.registerInstance(applicationName, ip, port); - log.debug( - "Health check success. register this instance. applicationName = {}, ip = {}, port = {}, status = {}", - applicationName, ip, port, status); + if (needRegister(applicationName, ip, port, status)) { + this.sidecarDiscoveryClient.registerInstance(applicationName, ip, + port); + log.info( + "Polyglot service changed and Health check success. register the new instance. applicationName = {}, ip = {}, port = {}, status = {}", + applicationName, ip, port, status); + } } else { log.warn( "Health check failed. unregister this instance. applicationName = {}, ip = {}, port = {}, status = {}", applicationName, ip, port, status); this.sidecarDiscoveryClient.deregisterInstance(applicationName, ip, port); + + sidecarInstanceCacheMap.put(applicationName, + buildCache(ip, port, status)); } }, 0, sidecarProperties.getHealthCheckInterval(), TimeUnit.MILLISECONDS); } + private void instanceCache(String applicationName, String ip, Integer port, + Status status) { + sidecarInstanceCacheMap.putIfAbsent(applicationName, + buildCache(ip, port, status)); + } + + private boolean needRegister(String applicationName, String ip, Integer port, + Status status) { + SidecarInstanceCache cacheRecord = sidecarInstanceCacheMap.get(applicationName); + SidecarInstanceCache cache = buildCache(ip, port, status); + + if (!Objects.equals(cache, cacheRecord)) { + // modify the cache info + sidecarInstanceCacheMap.put(applicationName, cache); + return true; + } + return false; + } + + private SidecarInstanceCache buildCache(String ip, Integer port, Status status) { + SidecarInstanceCache cache = new SidecarInstanceCache(); + cache.setIp(ip); + cache.setPort(port); + cache.setStatus(status); + return cache; + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarInstanceCache.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarInstanceCache.java new file mode 100644 index 000000000..0c18f1aa4 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarInstanceCache.java @@ -0,0 +1,76 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.cloud.sidecar; + +import java.util.Objects; + +import org.springframework.boot.actuate.health.Status; + +/** + * @author yuhuangbin + */ +public class SidecarInstanceCache { + + private String ip; + + private Integer port; + + private Status status; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SidecarInstanceCache that = (SidecarInstanceCache) o; + return Objects.equals(ip, that.ip) && Objects.equals(port, that.port) + && Objects.equals(status, that.status); + } + + @Override + public int hashCode() { + return Objects.hash(ip, port, status); + } + +}