diff --git a/pom.xml b/pom.xml
index cfdbdbf9..91895a2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,7 +88,7 @@
1.7.25
- 2.7.4.1
+ 2.7.6
4.0.1
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java
index c8c61700..efe083ea 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java
@@ -30,7 +30,7 @@ import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.client.RestTemplate;
-import static org.apache.dubbo.rpc.cluster.Constants.DEFAULT_RETRIES;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_RETRIES;
/**
* {@link DubboTransported @DubboTransported} annotation indicates that the traditional
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java
index 0ea71581..4a4502de 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java
@@ -29,7 +29,7 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;
import static com.alibaba.cloud.dubbo.registry.SpringCloudRegistryFactory.PROTOCOL;
-import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getPrefixedProperties;
+import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
/**
* Missing {@link SpringCloudRegistry} Property {@link Condition}.
@@ -61,7 +61,7 @@ public class MissingSpringCloudRegistryConfigPropertyCondition
"'spring-cloud' protocol was found from 'dubbo.registry.address'");
}
- Map properties = getPrefixedProperties(
+ Map properties = getSubProperties(
environment.getPropertySources(), "dubbo.registries.");
boolean found = properties.entrySet().stream().anyMatch(entry -> {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java
index 4de58946..10b7b743 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java
@@ -35,7 +35,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_PROTOCOL;
-import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getPrefixedProperties;
+import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
/**
* Dubbo {@link WebApplicationType#NONE Non-Web Application}
@@ -149,7 +149,7 @@ public class DubboNonWebApplicationEnvironmentPostProcessor
String restPort = null;
- Map subProperties = getPrefixedProperties(
+ Map subProperties = getSubProperties(
environment.getPropertySources(), PROTOCOLS_PROPERTY_NAME_PREFIX);
Properties properties = new Properties();
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
index abd27b7f..7c7a57cb 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
@@ -22,6 +22,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -189,7 +190,7 @@ public class DubboServiceMetadataRepository
// //
private static Map getMap(Map> repository,
- String key) {
+ String key) {
return getOrDefault(repository, key, newHashMap());
}
@@ -289,9 +290,11 @@ public class DubboServiceMetadataRepository
serviceName);
}
- initSubscribedDubboMetadataService(serviceName);
- // mark this service name having been initialized
- initializedServices.add(serviceName);
+ if (initSubscribedDubboMetadataService(serviceName)) {
+ // mark this service name having been initialized
+ initializedServices.add(serviceName);
+ }
+
}
}
}
@@ -300,12 +303,19 @@ public class DubboServiceMetadataRepository
* Remove the metadata and initialized service of Dubbo Services if no there is no
* service instance.
* @param serviceName the service name
+ * @param url the meta service url
*/
- public void removeMetadataAndInitializedService(String serviceName) {
+ public void removeMetadataAndInitializedService(String serviceName, URL url) {
synchronized (monitor) {
initializedServices.remove(serviceName);
dubboRestServiceMetadataRepository.remove(serviceName);
- subscribedDubboMetadataServiceURLs.remove(serviceName);
+ // fix #1260 if the subscribedDubboMetadataServiceURLs removed fail,old meta
+ // information will be retained
+ if (DubboMetadataService.class.getName().equals(url.getServiceInterface())) {
+ String serviceKey = url.getServiceKey();
+ subscribedDubboMetadataServiceURLs.remove(serviceKey);
+ }
+
}
}
@@ -333,7 +343,7 @@ public class DubboServiceMetadataRepository
}
private void addDubboMetadataServiceURLsMetadata(Map metadata,
- List dubboMetadataServiceURLs) {
+ List dubboMetadataServiceURLs) {
String dubboMetadataServiceURLsJSON = jsonUtils.toJSON(dubboMetadataServiceURLs);
metadata.put(DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME,
dubboMetadataServiceURLsJSON);
@@ -380,7 +390,7 @@ public class DubboServiceMetadataRepository
}
public List findSubscribedDubboMetadataServiceURLs(String serviceName,
- String group, String version, String protocol) {
+ String group, String version, String protocol) {
String serviceKey = URL.buildKey(serviceName, group, version);
List urls = null;
@@ -460,7 +470,7 @@ public class DubboServiceMetadataRepository
}
public Integer getDubboProtocolPort(ServiceInstance serviceInstance,
- String protocol) {
+ String protocol) {
String protocolProperty = getDubboProtocolPropertyName(protocol);
Map metadata = serviceInstance.getMetadata();
String protocolPort = metadata.get(protocolProperty);
@@ -468,7 +478,7 @@ public class DubboServiceMetadataRepository
}
public List getExportedURLs(String serviceInterface, String group,
- String version) {
+ String version) {
String serviceKey = URL.buildKey(serviceInterface, group, version);
return allExportedURLs.getOrDefault(serviceKey, Collections.emptyList());
}
@@ -525,7 +535,7 @@ public class DubboServiceMetadataRepository
* @return {@link DubboRestServiceMetadata} if matched, or null
*/
public DubboRestServiceMetadata get(String serviceName,
- RequestMetadata requestMetadata) {
+ RequestMetadata requestMetadata) {
return match(dubboRestServiceMetadataRepository, serviceName, requestMetadata);
}
@@ -542,7 +552,7 @@ public class DubboServiceMetadataRepository
}
private T match(Map> repository,
- String serviceName, RequestMetadata requestMetadata) {
+ String serviceName, RequestMetadata requestMetadata) {
Map map = repository.get(serviceName);
@@ -614,24 +624,47 @@ public class DubboServiceMetadataRepository
subscribedServices.remove(currentApplicationName);
}
- protected void initSubscribedDubboMetadataService(String serviceName) {
- metadataServiceInstanceSelector.choose(discoveryClient.getInstances(serviceName))
- .map(this::getDubboMetadataServiceURLs)
- .ifPresent(dubboMetadataServiceURLs -> {
- dubboMetadataServiceURLs.forEach(dubboMetadataServiceURL -> {
- try {
- initSubscribedDubboMetadataServiceURL(
- dubboMetadataServiceURL);
- initDubboMetadataServiceProxy(dubboMetadataServiceURL);
- }
- catch (Throwable e) {
- if (logger.isErrorEnabled()) {
- logger.error(e.getMessage(), e);
- }
- }
- });
- });
+ protected Boolean initSubscribedDubboMetadataService(String serviceName) {
+ // this need to judge whether the initialization is successful or not. The failed
+ // initialization will not change the initializedServices
+ Optional optionalServiceInstance = metadataServiceInstanceSelector
+ .choose(discoveryClient.getInstances(serviceName));
+ if (!((Optional) optionalServiceInstance).isPresent()) {
+ return false;
+ }
+ ServiceInstance serviceInstance = optionalServiceInstance.get();
+ if (null == serviceInstance) {
+ return false;
+ }
+ List dubboMetadataServiceURLs = getDubboMetadataServiceURLs(serviceInstance);
+ if (dubboMetadataServiceURLs.isEmpty()) {
+ return false;
+ }
+ for (URL dubboMetadataServiceURL : dubboMetadataServiceURLs) {
+ try {
+ initSubscribedDubboMetadataServiceURL(dubboMetadataServiceURL);
+ DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy
+ .getProxy(serviceName);
+ if (dubboMetadataService == null) {
+ dubboMetadataService = initDubboMetadataServiceProxy(
+ dubboMetadataServiceURL);
+ }
+
+ if (dubboMetadataService == null) {
+ removeMetadataAndInitializedService(serviceName,
+ dubboMetadataServiceURL);
+ return false;
+ }
+ }
+ catch (Throwable e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(e.getMessage(), e);
+ }
+ return false;
+ }
+ }
initDubboRestServiceMetadataRepository(serviceName);
+ return true;
}
private void initSubscribedDubboMetadataServiceURL(URL dubboMetadataServiceURL) {
@@ -640,11 +673,13 @@ public class DubboServiceMetadataRepository
subscribedDubboMetadataServiceURLs.add(serviceKey, dubboMetadataServiceURL);
}
- private void initDubboMetadataServiceProxy(URL dubboMetadataServiceURL) {
+ private DubboMetadataService initDubboMetadataServiceProxy(
+ URL dubboMetadataServiceURL) {
String serviceName = dubboMetadataServiceURL.getParameter(APPLICATION_KEY);
String version = dubboMetadataServiceURL.getParameter(VERSION_KEY);
// Initialize DubboMetadataService with right version
- dubboMetadataConfigServiceProxy.initProxy(serviceName, version);
+ return dubboMetadataConfigServiceProxy.initProxy(serviceName, version);
+
}
@Override
@@ -653,4 +688,4 @@ public class DubboServiceMetadataRepository
this.applicationEventPublisher = applicationEventPublisher;
}
-}
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java
index ce69c823..b4f656b2 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java
@@ -48,9 +48,11 @@ import static java.util.Collections.emptyList;
import static org.apache.dubbo.common.URLBuilder.from;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL;
import static org.springframework.util.StringUtils.hasText;
@@ -96,10 +98,10 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
private final ConfigurableApplicationContext applicationContext;
public AbstractSpringCloudRegistry(URL url, DiscoveryClient discoveryClient,
- DubboServiceMetadataRepository dubboServiceMetadataRepository,
- DubboMetadataServiceProxy dubboMetadataConfigServiceProxy,
- JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory,
- ConfigurableApplicationContext applicationContext) {
+ DubboServiceMetadataRepository dubboServiceMetadataRepository,
+ DubboMetadataServiceProxy dubboMetadataConfigServiceProxy,
+ JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory,
+ ConfigurableApplicationContext applicationContext) {
super(url);
this.servicesLookupInterval = url
.getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L);
@@ -161,6 +163,13 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
}
else if (isDubboMetadataServiceURL(url)) { // for DubboMetadataService
subscribeDubboMetadataServiceURLs(url, listener);
+ if (from(url).getParameter(CATEGORY_KEY) != null
+ && from(url).getParameter(CATEGORY_KEY).contains(PROVIDER)) {
+ // Fix #1259 and #753 Listene meta service change events to remove useless
+ // clients
+ registerServiceInstancesChangedEventListener(url, listener);
+ }
+
}
else { // for general Dubbo Services
subscribeDubboServiceURLs(url, listener);
@@ -181,7 +190,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
* @param listener {@link NotifyListener}
*/
private void registerServiceInstancesChangedEventListener(URL url,
- NotifyListener listener) {
+ NotifyListener listener) {
String listenerId = generateId(url);
if (registerListeners.add(listenerId)) {
applicationContext.addApplicationListener(
@@ -208,8 +217,8 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
}
protected void subscribeDubboServiceURL(URL url, NotifyListener listener,
- String serviceName,
- Function> serviceInstancesFunction) {
+ String serviceName,
+ Function> serviceInstancesFunction) {
if (logger.isInfoEnabled()) {
logger.info(
@@ -228,10 +237,13 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
// Re-obtain the latest list of available metadata address here, ip or port may
// change.
// by https://github.com/wangzihaogithub
- dubboMetadataConfigServiceProxy.removeProxy(serviceName);
- repository.removeMetadataAndInitializedService(serviceName);
- dubboGenericServiceFactory.destroy(serviceName);
- repository.initializeMetadata(serviceName);
+ // When the last service provider is closed, 【fix 1259】while close the
+ // channel,when up a new provider then repository.initializeMetadata(serviceName)
+ // will throw Exception.
+ // dubboMetadataConfigServiceProxy.removeProxy(serviceName);
+ // repository.removeMetadataAndInitializedService(serviceName);
+ // dubboGenericServiceFactory.destroy(serviceName);
+ // repository.initializeMetadata(serviceName);
if (CollectionUtils.isEmpty(serviceInstances)) {
if (logger.isWarnEnabled()) {
logger.warn(
@@ -239,6 +251,18 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
+ "available , please make sure the further impact",
serviceName, url.getServiceKey());
}
+ if (isDubboMetadataServiceURL(url)) {
+ // if meta service change, and serviceInstances is zero, will clean up
+ // information about this client
+ dubboMetadataConfigServiceProxy.removeProxy(serviceName);
+ repository.removeMetadataAndInitializedService(serviceName, url);
+ dubboGenericServiceFactory.destroy(serviceName);
+ String listenerId = generateId(url);
+ // The metaservice will restart the new listener. It needs to be optimized
+ // to see whether the original listener can be reused.
+ this.registerListeners.remove(listenerId);
+ }
+
/**
* URLs with {@link RegistryConstants#EMPTY_PROTOCOL}
*/
@@ -250,6 +274,11 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
listener.notify(allSubscribedURLs);
return;
}
+ if (isDubboMetadataServiceURL(url)) {
+ // Prevent duplicate generation of DubboMetadataService
+ return;
+ }
+ repository.initializeMetadata(serviceName);
DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy
.getProxy(serviceName);
@@ -301,7 +330,11 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
}
private List emptyURLs(URL url) {
- return asList(from(url).setProtocol(EMPTY_PROTOCOL).build());
+ // issue : When the last service provider is closed, the client still periodically
+ // connects to the last provider.n
+ // fix https://github.com/alibaba/spring-cloud-alibaba/issues/1259
+ return asList(from(url).setProtocol(EMPTY_PROTOCOL).removeParameter(CATEGORY_KEY)
+ .build());
}
private List getServiceInstances(String serviceName) {
@@ -322,7 +355,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
}
private List getExportedURLs(DubboMetadataService dubboMetadataService,
- URL url) {
+ URL url) {
String serviceInterface = url.getServiceInterface();
String group = url.getParameter(GROUP_KEY);
String version = url.getParameter(VERSION_KEY);
@@ -365,4 +398,4 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
}
-}
+}
\ No newline at end of file