From 9702156161a67e256e0044e901b801dd4ad6a222 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 4 Jun 2019 20:58:03 +0800 Subject: [PATCH] Polish apache/incubator-dubbo#4050 : Dubbo Cloud Native : Add a mechanism to upgrade Dubbo services smoothly --- .../apache/dubbo/config/api/DemoService.java | 6 +-- ...tedServicesRevisionMetadataCustomizer.java | 27 +++++++------ .../support/ServiceOrientedRegistry.java | 39 +++++++++++++++---- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/api/DemoService.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/api/DemoService.java index 30d745e84aa..f5afc9fefae 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/api/DemoService.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/api/DemoService.java @@ -34,7 +34,7 @@ public interface DemoService { int echo(int i); - default String name() { - return getClass().getSimpleName(); - } +// default String name() { +// return getClass().getSimpleName(); +// } } \ No newline at end of file diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java index 6d7b50af401..5c1cc8e9d11 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java @@ -33,6 +33,8 @@ /** * The customizer to a add the metadata that the reversion of Dubbo exported services calculates. + *

+ * The reversion is calculated on the methods that all Dubbo exported interfaces declare * * @since 2.7.3 */ @@ -48,17 +50,20 @@ protected String buildMetadataValue(ServiceInstance serviceInstance) { LocalMetadataService localMetadataService = LocalMetadataService.getDefaultExtension(); List exportedURLs = localMetadataService.getExportedURLs(); Object[] data = exportedURLs.stream() - .map(URL::valueOf) - .map(URL::getServiceInterface) - .filter(name -> !MetadataService.class.getName().equals(name)) - .map(ClassUtils::forName) - .map(Class::getMethods) - .map(Arrays::asList) - .flatMap(Collection::stream) - .map(Object::toString) - .sorted() - .toArray(); + .map(URL::valueOf) // String to URL + .map(URL::getServiceInterface) // get the service interface + .filter(this::isNotMetadataService) // filter not MetadataService interface + .map(ClassUtils::forName) // load business interface class + .map(Class::getMethods) // get all public methods from business interface + .map(Arrays::asList) // Array to List + .flatMap(Collection::stream) // flat Stream to be Stream + .map(Object::toString) // Method to String + .sorted() // sort methods marking sure the calculation of reversion is stable + .toArray(); // Stream to Array + return valueOf(hash(data)); // calculate the hash code as reversion + } - return valueOf(hash(data)); + private boolean isNotMetadataService(String serviceInterface) { + return !MetadataService.class.getName().equals(serviceInterface); } } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/ServiceOrientedRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/ServiceOrientedRegistry.java index 0e7edaafd48..535864f7b26 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/ServiceOrientedRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/ServiceOrientedRegistry.java @@ -42,6 +42,7 @@ import java.util.Set; import java.util.stream.Collectors; +import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableSet; @@ -142,11 +143,11 @@ public void doRegister(URL url) { } if (localMetadataService.exportURL(url)) { if (logger.isInfoEnabled()) { - logger.info(String.format("The URL[%s] registered successfully.", url.toString())); + logger.info(format("The URL[%s] registered successfully.", url.toString())); } } else { if (logger.isWarnEnabled()) { - logger.info(String.format("The URL[%s] has been registered.", url.toString())); + logger.info(format("The URL[%s] has been registered.", url.toString())); } } } @@ -158,11 +159,11 @@ public void doUnregister(URL url) { } if (localMetadataService.unexportURL(url)) { if (logger.isInfoEnabled()) { - logger.info(String.format("The URL[%s] deregistered successfully.", url.toString())); + logger.info(format("The URL[%s] deregistered successfully.", url.toString())); } } else { if (logger.isWarnEnabled()) { - logger.info(String.format("The URL[%s] has been deregistered.", url.toString())); + logger.info(format("The URL[%s] has been deregistered.", url.toString())); } } } @@ -194,11 +195,12 @@ public void destroy() { protected void subscribeURLs(URL url, NotifyListener listener) { + localMetadataService.subscribeURL(url); + Set serviceNames = getServices(url); serviceNames.forEach(serviceName -> subscribeURLs(url, listener, serviceName)); - localMetadataService.subscribeURL(url); } protected void subscribeURLs(URL url, NotifyListener listener, String serviceName) { @@ -217,7 +219,7 @@ protected void subscribeURLs(URL subscribedURL, NotifyListener listener, String Collection serviceInstances) { if (isEmpty(serviceInstances)) { - logger.warn(String.format("There is no instance in service[name : %s]", serviceName)); + logger.warn(format("There is no instance in service[name : %s]", serviceName)); return; } @@ -350,7 +352,30 @@ protected List getTemplateURLs(URL subscribedURL, ServiceInstance selectedI Map> revisionURLsCache) { // get the revision from the specified {@link ServiceInstance} String revision = getExportedServicesRevision(selectedInstance); - return revisionURLsCache.computeIfAbsent(revision, key -> getProviderExportedURLs(subscribedURL, selectedInstance)); + // try to get templateURLs from cache + List templateURLs = revisionURLsCache.get(revision); + + if (isEmpty(templateURLs)) { // not exists or getting failed last time + + if (!revisionURLsCache.isEmpty()) { // it's not first time + if (logger.isWarnEnabled()) { + logger.warn(format("The ServiceInstance[id: %s, host : %s , port : %s] has different revision : %s" + + ", please make sure the service [name : %s] is changing or not.", + selectedInstance.getId(), + selectedInstance.getHost(), + selectedInstance.getPort(), + revision, + selectedInstance.getServiceName() + )); + } + } + // get or get again + templateURLs = getProviderExportedURLs(subscribedURL, selectedInstance); + // put into cache + revisionURLsCache.put(revision, templateURLs); + } + + return templateURLs; } /**