From 4a1da760be13874b159871722f0b6262be8f69cf Mon Sep 17 00:00:00 2001 From: liubao68 Date: Mon, 23 Oct 2023 10:59:16 +0800 Subject: [PATCH] [SCB-2813]Nacos implementation not properly handle instance change (#3982) --- .../rest/locator/ServicePathManager.java | 9 --- demo/demo-nacos/consumer/pom.xml | 4 ++ demo/demo-nacos/gateway/pom.xml | 4 ++ demo/demo-nacos/pom.xml | 14 ---- demo/demo-nacos/provider/pom.xml | 4 ++ demo/demo-nacos/test-client/pom.xml | 13 ++-- .../samples/TestClientApplication.java | 6 +- .../src/main/resources/application.yml | 4 -- .../apache/servicecomb/samples/NocasIT.java | 36 +++++------ .../nacos/NacosDynamicPropertiesSource.java | 2 +- .../foundation/metrics/MetricsBootstrap.java | 2 +- .../metrics/MetricsBootstrapConfig.java | 2 +- .../registry/DiscoveryManager.java | 64 +++++++++++-------- .../discovery/StatefulDiscoveryInstance.java | 10 +-- .../common/utils/SPIServiceUtils.java | 5 +- .../registry/nacos/NacosConfiguration.java | 12 +--- .../registry/nacos/NacosDiscovery.java | 45 +++++++++---- .../nacos/NacosDiscoveryInstance.java | 8 ++- .../registry/nacos/NacosRegistration.java | 24 ++----- .../registry/nacos/NamingServiceManager.java | 20 ------ 20 files changed, 135 insertions(+), 153 deletions(-) rename service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/InstancesChangeEventListener.java => demo/demo-nacos/test-client/src/test/java/org/apache/servicecomb/samples/NocasIT.java (51%) diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/ServicePathManager.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/ServicePathManager.java index 0876f432f8f..d59d7019bc9 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/ServicePathManager.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/ServicePathManager.java @@ -27,16 +27,12 @@ import org.apache.servicecomb.core.definition.SchemaMeta; import org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext; import org.apache.servicecomb.registry.definition.DefinitionConst; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * 对静态路径和动态路径的operation进行预先处理,加速operation的查询定位 */ public class ServicePathManager { - private static final Logger LOGGER = LoggerFactory.getLogger(ServicePathManager.class); - private static final String REST_PATH_MANAGER = "RestServicePathManager"; protected MicroserviceMeta microserviceMeta; @@ -71,11 +67,6 @@ private void addSchema(SchemaMeta schemaMeta) { operationMeta.putExtData(RestConst.SWAGGER_REST_OPERATION, restOperationMeta); addResource(restOperationMeta); } - - LOGGER.info("add schema to service paths. {}:{}:{}.", - schemaMeta.getAppId(), - schemaMeta.getMicroserviceName(), - schemaMeta.getSchemaId()); } public OperationLocator consumerLocateOperation(String path, String httpMethod) { diff --git a/demo/demo-nacos/consumer/pom.xml b/demo/demo-nacos/consumer/pom.xml index d1d46fbb5b0..5a223fdb83a 100644 --- a/demo/demo-nacos/consumer/pom.xml +++ b/demo/demo-nacos/consumer/pom.xml @@ -34,6 +34,10 @@ org.apache.servicecomb java-chassis-spring-boot-starter-standalone + + org.apache.servicecomb + registry-nacos + diff --git a/demo/demo-nacos/gateway/pom.xml b/demo/demo-nacos/gateway/pom.xml index 157bfa5d948..f1135e3ab11 100644 --- a/demo/demo-nacos/gateway/pom.xml +++ b/demo/demo-nacos/gateway/pom.xml @@ -38,6 +38,10 @@ org.apache.servicecomb edge-core + + org.apache.servicecomb + registry-nacos + diff --git a/demo/demo-nacos/pom.xml b/demo/demo-nacos/pom.xml index 5c82f13c086..20c38c7d88d 100644 --- a/demo/demo-nacos/pom.xml +++ b/demo/demo-nacos/pom.xml @@ -33,20 +33,6 @@ org.apache.servicecomb solution-basic - - org.apache.servicecomb - registry-nacos - - - org.apache.servicecomb - servicestage-environment - - - org.apache.servicecomb - registry-service-center - - - org.apache.logging.log4j log4j-slf4j-impl diff --git a/demo/demo-nacos/provider/pom.xml b/demo/demo-nacos/provider/pom.xml index 9f930ab78e2..d80ae394c40 100644 --- a/demo/demo-nacos/provider/pom.xml +++ b/demo/demo-nacos/provider/pom.xml @@ -38,6 +38,10 @@ org.apache.servicecomb java-chassis-spring-boot-starter-standalone + + org.apache.servicecomb + registry-nacos + diff --git a/demo/demo-nacos/test-client/pom.xml b/demo/demo-nacos/test-client/pom.xml index 6015c22f73c..1ad589a02f6 100644 --- a/demo/demo-nacos/test-client/pom.xml +++ b/demo/demo-nacos/test-client/pom.xml @@ -42,17 +42,12 @@ org.apache.servicecomb.demo demo-schema + + org.apache.servicecomb + registry-local + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - docker diff --git a/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java b/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java index 10d62c6bba4..26a2a491bbe 100644 --- a/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java +++ b/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java @@ -33,7 +33,7 @@ public static void main(String[] args) throws Exception { try { new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args); - CategorizedTestCaseRunner.runCategorizedTestCase("consumer"); + run(); } catch (Exception e) { TestMgr.failed("test case run failed", e); LOGGER.error("-------------- test failed -------------"); @@ -42,4 +42,8 @@ public static void main(String[] args) throws Exception { } TestMgr.summary(); } + + public static void run() throws Exception { + CategorizedTestCaseRunner.runCategorizedTestCase("consumer"); + } } diff --git a/demo/demo-nacos/test-client/src/main/resources/application.yml b/demo/demo-nacos/test-client/src/main/resources/application.yml index 5caa50190ab..2e8b29356b3 100644 --- a/demo/demo-nacos/test-client/src/main/resources/application.yml +++ b/demo/demo-nacos/test-client/src/main/resources/application.yml @@ -20,10 +20,6 @@ servicecomb: application: demo-nacos name: test-client version: 0.0.1 - registry: - nacos: - enabled: true - serverAddr: ${PAAS_CSE_NACOS_ENDPOINT:http://127.0.0.1:8848} rest: address: 0.0.0.0:9097 # should be same with server.port to use web container diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/InstancesChangeEventListener.java b/demo/demo-nacos/test-client/src/test/java/org/apache/servicecomb/samples/NocasIT.java similarity index 51% rename from service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/InstancesChangeEventListener.java rename to demo/demo-nacos/test-client/src/test/java/org/apache/servicecomb/samples/NocasIT.java index 12c56fc91e0..bc7b5a6b9ba 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/InstancesChangeEventListener.java +++ b/demo/demo-nacos/test-client/src/test/java/org/apache/servicecomb/samples/NocasIT.java @@ -15,29 +15,29 @@ * limitations under the License. */ -package org.apache.servicecomb.registry.nacos; +package org.apache.servicecomb.samples; -import org.springframework.beans.factory.annotation.Autowired; +import org.apache.servicecomb.demo.TestMgr; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.alibaba.nacos.client.naming.event.InstancesChangeEvent; -import com.alibaba.nacos.common.notify.Event; -import com.alibaba.nacos.common.notify.listener.Subscriber; +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = TestClientApplication.class) +public class NocasIT { -public class InstancesChangeEventListener extends Subscriber { - private final NacosDiscovery nacosDiscovery; - - @Autowired - public InstancesChangeEventListener(NacosDiscovery nacosDiscovery) { - this.nacosDiscovery = nacosDiscovery; + @BeforeEach + public void setUp() { + TestMgr.errors().clear(); } - @Override - public void onEvent(InstancesChangeEvent event) { - nacosDiscovery.onInstanceChangedEvent(event); - } + @Test + public void clientGetsNoError() throws Exception { + TestClientApplication.run(); - @Override - public Class subscribeType() { - return InstancesChangeEvent.class; + Assertions.assertTrue(TestMgr.errors().isEmpty()); } } diff --git a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosDynamicPropertiesSource.java b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosDynamicPropertiesSource.java index 1ee1750f9f1..a533d22bd43 100644 --- a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosDynamicPropertiesSource.java +++ b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosDynamicPropertiesSource.java @@ -33,7 +33,7 @@ import com.google.common.annotations.VisibleForTesting; public class NacosDynamicPropertiesSource implements DynamicPropertiesSource { - public static final String SOURCE_NAME = "kie"; + public static final String SOURCE_NAME = "nacos"; private static final Logger LOGGER = LoggerFactory.getLogger(NacosDynamicPropertiesSource.class); diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java index 977ed1b1a51..5b014afe8d9 100644 --- a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java @@ -80,7 +80,7 @@ public void shutdown() { protected void startPoll() { executorService.scheduleAtFixedRate(this::pollMeters, - 0, + config.getMsPollInterval(), config.getMsPollInterval(), TimeUnit.MILLISECONDS); } diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java index db7dcb4959b..53ab9a6d6ff 100644 --- a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java @@ -26,7 +26,7 @@ public class MetricsBootstrapConfig { public static final String CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN = "servicecomb.metrics.publisher.defaultLog.invocation.latencyDistribution.minScopeLength"; - public static final int DEFAULT_METRICS_WINDOW_TIME = 60000; + public static final int DEFAULT_METRICS_WINDOW_TIME = 300_000; private long msPollInterval; diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java index 378010ff519..8280199ddda 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java @@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.lang3.StringUtils; import org.apache.servicecomb.foundation.common.cache.VersionedCache; import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; import org.apache.servicecomb.registry.api.Discovery; @@ -98,7 +97,7 @@ private void doTask() { changed = true; } // check ping status - if (System.currentTimeMillis() - instance.getPingSuccessTime() > 180_000L) { + if (System.currentTimeMillis() - instance.getPingTime() > 180_000L) { boolean pingResult = ping.ping(instance); if (pingResult && instance.getPingStatus() != PingStatus.OK) { instance.setPingStatus(PingStatus.OK); @@ -107,9 +106,7 @@ private void doTask() { instance.setPingStatus(PingStatus.FAIL); changed = true; } - if (pingResult) { - instance.setPingSuccessTime(System.currentTimeMillis()); - } + instance.setPingTime(System.currentTimeMillis()); } // check unused if (instance.getHistoryStatus() == HistoryStatus.HISTORY) { @@ -118,11 +115,16 @@ private void doTask() { instance.getIsolationStatus() == IsolationStatus.ISOLATED) { removed.computeIfAbsent(apps.getKey(), k -> new HashMap<>()) .computeIfAbsent(services.getKey(), k -> new ArrayList<>()).add(instance.getInstanceId()); + LOGGER.info("Remove instance {}/{}/{}/{}/{}/{}/{}/{}", + apps.getKey(), services.getKey(), instance.getRegistryName(), + instance.getInstanceId(), instance.getHistoryStatus(), + instance.getStatus(), instance.getPingStatus(), instance.getIsolationStatus()); + changed = true; } } } if (changed) { - rebuildVersionCache(apps.getKey(), apps.getKey()); + rebuildVersionCache(apps.getKey(), services.getKey()); } } } @@ -130,12 +132,7 @@ private void doTask() { for (Entry>> apps : removed.entrySet()) { for (Entry> services : apps.getValue().entrySet()) { for (String instance : services.getValue()) { - StatefulDiscoveryInstance removedInstance = - allInstances.get(apps.getKey()).get(services.getKey()).remove(instance); - LOGGER.info("Remove instance {}/{}/{}/{}/{}/{}/{}/{}", - apps.getKey(), services.getKey(), removedInstance.getRegistryName(), - instance, removedInstance.getHistoryStatus(), - removedInstance.getStatus(), removedInstance.getPingStatus(), removedInstance.getIsolationStatus()); + allInstances.get(apps.getKey()).get(services.getKey()).remove(instance); } } } @@ -152,27 +149,28 @@ private void onInstancesChanged(String registryName, String application, String new ConcurrentHashMapEx<>()).computeIfAbsent(serviceName, key -> new ConcurrentHashMapEx<>()); for (StatefulDiscoveryInstance statefulInstance : statefulInstances.values()) { - if (StringUtils.isEmpty(registryName)) { - statefulInstance.setHistoryStatus(HistoryStatus.HISTORY); - continue; - } - if (registryName.equals(statefulInstance.getRegistryName())) { - statefulInstance.setHistoryStatus(HistoryStatus.HISTORY); + if (registryName == null || registryName.equals(statefulInstance.getRegistryName())) { + if (!instances.contains(statefulInstance)) { + statefulInstance.setPingTime(0); + statefulInstance.setHistoryStatus(HistoryStatus.HISTORY); + } } } for (DiscoveryInstance instance : instances) { - StatefulDiscoveryInstance target = statefulInstances.get(instance.getInstanceId()); - if (target == null) { - statefulInstances.put(instance.getInstanceId(), new StatefulDiscoveryInstance(instance)); + StatefulDiscoveryInstance target = new StatefulDiscoveryInstance(instance); + StatefulDiscoveryInstance origin = statefulInstances.get(instance.getInstanceId()); + if (origin == null) { + statefulInstances.put(instance.getInstanceId(), target); continue; } - target.setHistoryStatus(HistoryStatus.CURRENT); - target.setMicroserviceInstanceStatus(instance.getStatus()); + target.setPingTime(origin.getPingTime()); + target.setPingStatus(origin.getPingStatus()); + target.setIsolateDuration(origin.getIsolateDuration()); + target.setIsolationStatus(origin.getIsolationStatus()); + statefulInstances.put(instance.getInstanceId(), target); } - rebuildVersionCache(application, serviceName); - StringBuilder instanceInfo = new StringBuilder(); for (DiscoveryInstance instance : instances) { instanceInfo.append("{") @@ -184,6 +182,8 @@ private void onInstancesChanged(String registryName, String application, String } LOGGER.info("Applying new instance list for {}/{}/{}. Endpoints {}", application, serviceName, instances.size(), instanceInfo); + + rebuildVersionCache(application, serviceName); } public void onInstanceIsolated(StatefulDiscoveryInstance instance, long isolateDuration) { @@ -233,6 +233,20 @@ private VersionedCache calcAvailableInstance(String application, String serviceN result.add(instance); } } + StringBuilder instanceInfo = new StringBuilder(); + for (StatefulDiscoveryInstance instance : result) { + instanceInfo.append("{") + .append(instance.getInstanceId()).append(",") + .append(instance.getHistoryStatus()).append(",") + .append(instance.getStatus()).append(",") + .append(instance.getPingStatus()).append(",") + .append(instance.getIsolationStatus()).append(",") + .append(instance.getEndpoints()).append(",") + .append(instance.getRegistryName()) + .append("}"); + } + LOGGER.info("Rebuild cached instance list for {}/{}/{}. Endpoints {}", + application, serviceName, result.size(), instanceInfo); return new VersionedCache() .name(application + ":" + serviceName) .autoCacheVersion() diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java index 58c50e70b76..fbcb1614330 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java @@ -56,7 +56,7 @@ public enum HistoryStatus { private PingStatus pingStatus = PingStatus.UNKNOWN; - private long pingSuccessTime; + private long pingTime = 0; private HistoryStatus historyStatus = HistoryStatus.CURRENT; @@ -114,12 +114,12 @@ public void setIsolateDuration(long isolateDuration) { this.isolateDuration = isolateDuration; } - public long getPingSuccessTime() { - return pingSuccessTime; + public long getPingTime() { + return pingTime; } - public void setPingSuccessTime(long pingSuccessTime) { - this.pingSuccessTime = pingSuccessTime; + public void setPingTime(long pingTime) { + this.pingTime = pingTime; } @Override diff --git a/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java index ea8a0bc12ea..abd2dcab32e 100644 --- a/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java +++ b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java @@ -76,11 +76,12 @@ public static List loadSortedService(Class serviceType) { .map(Entry::getValue) .collect(Collectors.toList()); - LOGGER.info("Found SPI service {}, count={}.", serviceType.getName(), services.size()); + StringBuilder info = new StringBuilder(); for (int idx = 0; idx < services.size(); idx++) { T service = services.get(idx); - LOGGER.info(" {}. {}.", idx, service.getClass().getName()); + info.append("{").append(idx).append(",").append(service.getClass().getSimpleName()).append("}"); } + LOGGER.info("Found SPI service {}, services={}.", serviceType.getSimpleName(), info); return services; } diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConfiguration.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConfiguration.java index e1cd555a9e1..2a1adbaae92 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConfiguration.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConfiguration.java @@ -36,10 +36,8 @@ public NacosDiscoveryProperties nacosDiscoveryProperties() { public NacosRegistration nacosRegistration( DataCenterProperties dataCenterProperties, @Qualifier("nacosDiscoveryProperties") NacosDiscoveryProperties nacosDiscoveryProperties, - Environment environment, - @Qualifier("instancesChangeEventListener") InstancesChangeEventListener instancesChangeEventListener) { - return new NacosRegistration(dataCenterProperties, nacosDiscoveryProperties, environment, - instancesChangeEventListener); + Environment environment) { + return new NacosRegistration(dataCenterProperties, nacosDiscoveryProperties, environment); } @Bean @@ -47,10 +45,4 @@ public NacosDiscovery nacosDiscovery( @Qualifier("nacosDiscoveryProperties") NacosDiscoveryProperties nacosDiscoveryProperties) { return new NacosDiscovery(nacosDiscoveryProperties); } - - @Bean - public InstancesChangeEventListener instancesChangeEventListener( - @Qualifier("nacosDiscovery") NacosDiscovery nacosDiscovery) { - return new InstancesChangeEventListener(nacosDiscovery); - } } diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java index a606342386b..87d03fa4649 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java @@ -19,21 +19,27 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.servicecomb.registry.api.Discovery; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.util.CollectionUtils; -import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.listener.NamingEvent; import com.alibaba.nacos.api.naming.pojo.Instance; -import com.alibaba.nacos.client.naming.event.InstancesChangeEvent; public class NacosDiscovery implements Discovery { public static final String NACOS_DISCOVERY_ENABLED = "servicecomb.registry.nacos.%s.%s.enabled"; + private static final Map> SUBSCRIBES = new HashMap<>(); + + private final Object lock = new Object(); + private final NacosDiscoveryProperties nacosDiscoveryProperties; private Environment environment; @@ -48,6 +54,7 @@ public NacosDiscovery(NacosDiscoveryProperties nacosDiscoveryProperties) { } @Autowired + @SuppressWarnings("unused") public void setEnvironment(Environment environment) { this.environment = environment; } @@ -66,20 +73,39 @@ public boolean enabled(String application, String serviceName) { @Override public List findServiceInstances(String application, String serviceName) { try { + AtomicBoolean result = SUBSCRIBES.computeIfAbsent(application, + k -> new HashMap<>()).computeIfAbsent(serviceName, k -> new AtomicBoolean(true)); + if (result.get()) { + synchronized (lock) { + if (result.get()) { + namingService.subscribe(serviceName, application, (event) -> { + if (result.getAndSet(false)) { + // ignore the first event. + return; + } + if (event instanceof NamingEvent) { + this.instanceChangedListener.onInstanceChanged(name(), application, serviceName, + convertServiceInstanceList(((NamingEvent) event).getInstances(), application, serviceName)); + } + }); + } + } + } List instances = namingService.getAllInstances(serviceName, application, true); - return convertServiceInstanceList(instances, application); - } catch (NacosException e) { - throw new IllegalStateException("updateMicroserviceInstanceStatus process is interrupted."); + return convertServiceInstanceList(instances, application, serviceName); + } catch (Exception e) { + throw new IllegalStateException(e); } } - private List convertServiceInstanceList(List instances, String application) { + private List convertServiceInstanceList( + List instances, String application, String serviceName) { if (CollectionUtils.isEmpty(instances)) { return Collections.emptyList(); } List result = new ArrayList<>(); for (Instance instance : instances) { - result.add(new NacosDiscoveryInstance(instance, application, environment)); + result.add(new NacosDiscoveryInstance(instance, application, serviceName, environment)); } return result; } @@ -89,11 +115,6 @@ public void setInstanceChangedListener(InstanceChangedListener schemas; private final List endpoints; - public NacosDiscoveryInstance(Instance instance, String application, + public NacosDiscoveryInstance(Instance instance, String application, String serviceName, Environment environment) { this.instance = instance; this.environment = environment; this.application = application; + this.serviceName = serviceName; this.endpoints = readEndpoints(instance); this.schemas = readSchemas(instance); } @@ -74,7 +77,8 @@ public String getApplication() { @Override public String getServiceName() { - return instance.getServiceName(); + // nacos instance service name may contain group and `@` annotations + return this.serviceName; } @Override diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java index 79cd5841185..97d016a975c 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java @@ -32,18 +32,14 @@ import org.springframework.util.CollectionUtils; 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.pojo.Instance; -import com.alibaba.nacos.common.notify.NotifyCenter; public class NacosRegistration implements Registration { private final NacosDiscoveryProperties nacosDiscoveryProperties; private final Environment environment; - private final InstancesChangeEventListener instancesChangeEventListener; - private final String instanceId; private final DataCenterProperties dataCenterProperties; @@ -54,16 +50,13 @@ public class NacosRegistration implements Registration