You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/11/23 03:12:18 UTC

[dubbo] 03/05: refactor

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 3.0-metadata-refactor
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit abba52d03140835235f5e02c86ee810805e28c9d
Author: ken.lj <ke...@gmail.com>
AuthorDate: Wed Nov 17 14:44:40 2021 +0800

    refactor
---
 .../dubbo/common/constants/CommonConstants.java    |   4 -
 .../dubbo/common/constants/RegistryConstants.java  |   6 +-
 .../config/deploy/DefaultApplicationDeployer.java  |   3 +
 .../ConfigurableMetadataServiceExporter.java       |  47 ++++----
 .../dubbo/config/mock/MockServiceDiscovery.java    |  20 ++--
 .../spring/registry/MockServiceDiscovery.java      |  20 ++--
 .../src/main/resources/spring/dubbo-provider.xml   |   2 +-
 .../dubbo/metadata/AbstractServiceNameMapping.java |  49 ++++++--
 .../org/apache/dubbo/metadata/MetadataInfo.java    |   2 +-
 .../org/apache/dubbo/metadata/MetadataService.java |  27 +----
 .../apache/dubbo/metadata/ServiceNameMapping.java  |  19 ++--
 .../metadata/report/MetadataReportInstance.java    |  13 +--
 .../report/support/AbstractMetadataReport.java     |   8 +-
 .../metadata/AbstractServiceNameMappingTest.java   |  55 ++++++++-
 .../org/apache/dubbo/maven/plugin/ClassFinder.java |   1 -
 .../java/org/apache/dubbo/maven/plugin/Test.java   |   4 -
 .../registry/client/AbstractServiceDiscovery.java  |  52 ++++++---
 .../registry/client/DefaultServiceInstance.java    |   6 +-
 .../dubbo/registry/client/InstanceAddressURL.java  |   6 +-
 .../dubbo/registry/client/ServiceDiscovery.java    | 124 ++-------------------
 .../registry/client/ServiceDiscoveryRegistry.java  |   6 +-
 .../metadata/MetadataServiceNameMapping.java       |  11 +-
 .../registry/client/metadata/MetadataUtils.java    |  14 +--
 .../client/support/MockServiceDiscovery.java       |  20 ++--
 .../support/MockServiceDiscoveryFactory.java       |   2 +-
 .../multicast/MulticastServiceDiscovery.java       |  21 ++--
 .../MulticastServiceDiscoveryFactory.java          |   2 +-
 .../multiple/MultipleServiceDiscovery.java         |  22 +---
 .../multiple/MultipleServiceDiscoveryFactory.java  |   2 +-
 .../registry/nacos/NacosServiceDiscovery.java      |  15 +--
 .../nacos/NacosServiceDiscoveryFactory.java        |   2 +-
 .../registry/nacos/NacosServiceDiscoveryTest.java  |   9 +-
 .../zookeeper/ZookeeperServiceDiscovery.java       |  78 ++-----------
 .../ZookeeperServiceDiscoveryFactory.java          |   2 +-
 .../zookeeper/util/CuratorFrameworkUtils.java      |   3 +-
 .../zookeeper/ZookeeperServiceDiscoveryTest.java   |   8 +-
 .../dubbo/rpc/protocol/dubbo/DubboProtocol.java    |   4 +-
 .../protocol/dubbo/LazyConnectExchangeClient.java  |   4 +-
 38 files changed, 289 insertions(+), 404 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index 70f3629..4ef883f 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -215,10 +215,6 @@ public interface CommonConstants {
 
     String METADATA_KEY = "metadata-type";
 
-    String CONFIG_MAPPING_TYPE = "config";
-
-    String METADATA_MAPPING_TYPE = "metadata";
-
     String DEFAULT_METADATA_STORAGE_TYPE = "local";
 
     String REMOTE_METADATA_STORAGE_TYPE = "remote";
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
index 6029293..4616427 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
@@ -100,11 +100,7 @@ public interface RegistryConstants {
     String SERVICE_REGISTRY_PROTOCOL = "service-discovery-registry";
 
     /**
-     * The parameter key of the subscribed service names for Service-Oriented Registry
-     * <p>
-     * If there is a multiple-values, the  "comma" is the separator.
-     *
-     * @since 2.7.5
+     * Specify registry level services consumer needs to subscribe to, multiple values should be separated using ",".
      */
     String SUBSCRIBED_SERVICE_NAMES_KEY = "subscribed-services";
 
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
index 6d91c69..a8a586f 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
@@ -295,6 +295,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
             }
             metadataReportInstance.init(metadataReportConfig);
         }
+        if (!metadataReportInstance.inited()) {
+            throw new IllegalStateException(String.format("%s MetadataConfigs found, but none of them is valid.", metadataReportConfigs.size()));
+        }
     }
 
     /**
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
index 89659fe..a9510b6 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
@@ -22,8 +22,6 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.ArgumentConfig;
-import org.apache.dubbo.config.MethodConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ServiceConfig;
@@ -35,7 +33,6 @@ import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ScopeModelAware;
 
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -97,7 +94,7 @@ public class ConfigurableMetadataServiceExporter implements MetadataServiceExpor
             serviceConfig.setRef(metadataService);
             serviceConfig.setGroup(applicationConfig.getName());
             serviceConfig.setVersion(metadataService.version());
-            serviceConfig.setMethods(generateMethodConfig());
+//            serviceConfig.setMethods(generateMethodConfig());
             serviceConfig.setConnections(1);
             serviceConfig.setExecutes(100);
 
@@ -119,27 +116,27 @@ public class ConfigurableMetadataServiceExporter implements MetadataServiceExpor
         return this;
     }
 
-    /**
-     * Generate Method Config for Service Discovery Metadata <p/>
-     * <p>
-     * Make {@link MetadataService} support argument callback,
-     * used to notify {@link org.apache.dubbo.registry.client.ServiceInstance}'s
-     * metadata change event
-     *
-     * @since 3.0
-     */
-    private List<MethodConfig> generateMethodConfig() {
-        MethodConfig methodConfig = new MethodConfig();
-        methodConfig.setName("getAndListenInstanceMetadata");
-
-        ArgumentConfig argumentConfig = new ArgumentConfig();
-        argumentConfig.setIndex(1);
-        argumentConfig.setCallback(true);
-
-        methodConfig.setArguments(Collections.singletonList(argumentConfig));
-
-        return Collections.singletonList(methodConfig);
-    }
+//    /**
+//     * Generate Method Config for Service Discovery Metadata <p/>
+//     * <p>
+//     * Make {@link MetadataService} support argument callback,
+//     * used to notify {@link org.apache.dubbo.registry.client.ServiceInstance}'s
+//     * metadata change event
+//     *
+//     * @since 3.0
+//     */
+//    private List<MethodConfig> generateMethodConfig() {
+//        MethodConfig methodConfig = new MethodConfig();
+//        methodConfig.setName("getAndListenInstanceMetadata");
+//
+//        ArgumentConfig argumentConfig = new ArgumentConfig();
+//        argumentConfig.setIndex(1);
+//        argumentConfig.setCallback(true);
+//
+//        methodConfig.setArguments(Collections.singletonList(argumentConfig));
+//
+//        return Collections.singletonList(methodConfig);
+//    }
 
     @Override
     public ConfigurableMetadataServiceExporter unexport() {
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java
index f736311..2e8f204 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java
@@ -21,23 +21,20 @@ import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 public class MockServiceDiscovery extends AbstractServiceDiscovery {
     private URL registryURL;
 
-    public MockServiceDiscovery(ApplicationModel applicationModel) {
-        super(applicationModel);
+    public MockServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        super(applicationModel, registryURL);
     }
 
-    public MockServiceDiscovery(String serviceName) {
-        super(serviceName);
-    }
-
-    @Override
-    public void doInitialize(URL registryURL) throws Exception {
-        this.registryURL = registryURL;
+    public MockServiceDiscovery(String serviceName, URL registryURL) {
+        super(serviceName, registryURL);
     }
 
     @Override
@@ -66,6 +63,11 @@ public class MockServiceDiscovery extends AbstractServiceDiscovery {
     }
 
     @Override
+    public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
+        return Collections.emptyList();
+    }
+
+    @Override
     public URL getUrl() {
         return registryURL;
     }
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registry/MockServiceDiscovery.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registry/MockServiceDiscovery.java
index 27c8f01..085a57b 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registry/MockServiceDiscovery.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/registry/MockServiceDiscovery.java
@@ -21,23 +21,20 @@ import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 public class MockServiceDiscovery extends AbstractServiceDiscovery {
     private URL registryURL;
 
-    public MockServiceDiscovery(ApplicationModel applicationModel) {
-        super(applicationModel);
+    public MockServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        super(applicationModel, registryURL);
     }
 
-    public MockServiceDiscovery(String serviceName) {
-        super(serviceName);
-    }
-
-    @Override
-    public void doInitialize(URL registryURL) throws Exception {
-        this.registryURL = registryURL;
+    public MockServiceDiscovery(String serviceName, URL registryURL) {
+        super(serviceName, registryURL);
     }
 
     @Override
@@ -63,6 +60,11 @@ public class MockServiceDiscovery extends AbstractServiceDiscovery {
     }
 
     @Override
+    public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
+        return Collections.emptyList();
+    }
+
+    @Override
     public URL getUrl() {
         return registryURL;
     }
diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/resources/spring/dubbo-provider.xml b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/resources/spring/dubbo-provider.xml
index 64c81e1..60f1d93 100644
--- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/resources/spring/dubbo-provider.xml
+++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/resources/spring/dubbo-provider.xml
@@ -21,7 +21,7 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
 
-    <dubbo:application name="demo-provider">
+    <dubbo:application name="demo-provider" metadata-type="remote">
     </dubbo:application>
 
     <dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
index 7ad3fa5..843529a 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
@@ -19,6 +19,7 @@ package org.apache.dubbo.metadata;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ScopeModelAware;
@@ -34,6 +35,7 @@ import static java.util.Collections.unmodifiableSet;
 import static java.util.stream.Collectors.toSet;
 import static java.util.stream.Stream.of;
 import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDED_BY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
 import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
 import static org.apache.dubbo.common.utils.StringUtils.isBlank;
 
@@ -74,8 +76,10 @@ public abstract class AbstractServiceNameMapping implements ServiceNameMapping,
             subscribedServices.addAll(parseServices(serviceNames));
         }
 
+        String key = ServiceNameMapping.buildMappingKey(subscribedURL);
+
         if (isEmpty(subscribedServices)) {
-            Set<String> cachedServices = this.getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
+            Set<String> cachedServices = this.getCachedMapping(key);
             if(!isEmpty(cachedServices)) {
                 subscribedServices.addAll(cachedServices);
             }
@@ -87,25 +91,50 @@ public abstract class AbstractServiceNameMapping implements ServiceNameMapping,
             subscribedServices.addAll(mappedServices);
         }
 
-        this.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL), subscribedServices);
+        this.putCachedMapping(key, subscribedServices);
 
         return subscribedServices;
     }
 
+    /**
+     * Register callback to listen to mapping changes.
+     *
+     * @return cached or remote mapping data
+     */
     @Override
     public Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener) {
+        String key = ServiceNameMapping.buildMappingKey(subscribedURL);
         // use previously cached services.
-        Set<String> cachedServices = this.getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
+        Set<String> cachedServices = this.getCachedMapping(key);
 
-        // Asynchronously register listener in case previous cache does not exist or cache updating in the future.
-        ExecutorService executorService = applicationModel.getApplicationExecutorRepository().nextExecutorExecutor();
-        executorService.submit(() -> {
+       Runnable runnable = () -> {
             synchronized (mappingListeners) {
-                Set<String> mappedServices = getAndListen(subscribedURL, listener);
-                this.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL), mappedServices);
-                mappingListeners.put(subscribedURL.getProtocolServiceKey(), listener);
+                if (listener != null) {
+                    Set<String> mappedServices = getAndListen(subscribedURL, listener);
+                    this.putCachedMapping(key, mappedServices);
+                    mappingListeners.put(subscribedURL.getProtocolServiceKey(), listener);
+                } else {
+                    Set<String> mappedServices = get(subscribedURL);
+                    this.putCachedMapping(key, mappedServices);
+                }
             }
-        });
+        };
+
+        // Asynchronously register listener in case previous cache does not exist or cache updating in the future.
+        if (CollectionUtils.isEmpty(cachedServices)) {
+            runnable.run();
+            cachedServices = this.getCachedMapping(key);
+            if (CollectionUtils.isEmpty(cachedServices)) {
+                String registryServices = registryURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY);
+                if (StringUtils.isNotEmpty(registryServices)) {
+                    logger.info(subscribedURL.getServiceInterface() + " mapping to " + registryServices + " instructed by registry subscribed-services.");
+                    cachedServices = parseServices(registryServices);
+                }
+            }
+        } else {
+            ExecutorService executorService = applicationModel.getApplicationExecutorRepository().nextExecutorExecutor();
+            executorService.submit(runnable);
+        }
 
         return cachedServices;
     }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
index df06767..8615ac7 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
@@ -111,7 +111,7 @@ public class MetadataInfo implements Serializable {
             return;
         }
         this.services.remove(url.getProtocolServiceKey());
-        this.exportedServiceURLs.remove(url);
+        removeURL(exportedServiceURLs, url);
 
         updated.compareAndSet(false, true);
     }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java
index 4606ed2..7276b07 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java
@@ -30,29 +30,19 @@ import static java.util.Collections.unmodifiableSortedSet;
 import static org.apache.dubbo.common.URL.buildKey;
 
 /**
- *
+ * This service is used to expose the metadata information inside a Dubbo process.
+ * Typical uses include:
+ * 1. The Consumer queries the metadata information of the Provider to list the interfaces and each interface's configuration
+ * 2. The Console (dubbo-admin) queries for the metadata of a specific process, or aggregate data of all processes.
  */
 public interface MetadataService {
 
-    //FIXME the value is default, it was used by testing temporarily
-    static final String DEFAULT_EXTENSION = "default";
-
-    /**
-     * The value of all service names
-     */
-    String ALL_SERVICE_NAMES = "*";
-
     /**
      * The value of All service instances
      */
     String ALL_SERVICE_INTERFACES = "*";
 
     /**
-     * The service interface name of {@link MetadataService}
-     */
-    String SERVICE_INTERFACE_NAME = MetadataService.class.getName();
-
-    /**
      * The contract version of {@link MetadataService}, the future update must make sure compatible.
      */
     String VERSION = "1.0.0";
@@ -164,15 +154,12 @@ public interface MetadataService {
         return getServiceDefinition(buildKey(interfaceName, group, version));
     }
 
-    /**
-     * Interface definition.
-     *
-     * @return
-     */
     String getServiceDefinition(String serviceKey);
 
     MetadataInfo getMetadataInfo(String revision);
 
+    List<MetadataInfo> getMetadataInfos();
+
     /**
      * Convert the specified {@link Iterable} of {@link URL URLs} to be the {@link URL#toFullString() strings} presenting
      * the {@link URL URLs}
@@ -197,6 +184,4 @@ public interface MetadataService {
         return unmodifiableSortedSet(stream.map(URL::toFullString).collect(TreeSet::new, Set::add, Set::addAll));
     }
 
-    List<MetadataInfo> getMetadataInfos();
-
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
index 459d299..6e88b7c 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
@@ -33,9 +33,9 @@ import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
 import static org.apache.dubbo.common.utils.StringUtils.SLASH;
 
 /**
- * The interface for Dubbo service name Mapping
+ * This will interact with remote metadata center to find the interface-app mapping and will cache the data locally.
  *
- * @since 2.7.5
+ * Call variants of getCachedMapping() methods whenever need to use the mapping data.
  */
 @SPI(value = "metadata", scope = APPLICATION)
 public interface ServiceNameMapping {
@@ -88,15 +88,20 @@ public interface ServiceNameMapping {
     }
 
     /**
-     * 1.developer explicitly specifies the application name this interface belongs to
-     * 2.check Interface-App mapping
+     * Get the mapping data from remote metadata center and cache in local storage.
+     *
+     * @return app list current interface mapping to, in sequence determined by:
+     * 1.check PROVIDED_BY
+     * 2.check remote metadata center
+     *
      */
     Set<String> getServices(URL subscribedURL);
 
     /**
-     * 1.developer explicitly specifies the application name this interface belongs to
-     * 2.check Interface-App mapping
-     * 3.use the services specified in registry url.
+     * Register listener to get notified once mapping data changes.
+     *
+     * @param listener
+     * @return
      */
     Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener);
 
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
index 0f2d364..848b2e9 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
@@ -79,14 +79,10 @@ public class MetadataReportInstance implements Disposable {
     }
 
     public Map<String, MetadataReport> getMetadataReports(boolean checked) {
-        if (checked) {
-            checkInit();
-        }
         return metadataReports;
     }
 
     public MetadataReport getMetadataReport(String registryKey) {
-        checkInit();
         MetadataReport metadataReport = metadataReports.get(registryKey);
         if (metadataReport == null) {
             metadataReport = metadataReports.values().iterator().next();
@@ -94,17 +90,14 @@ public class MetadataReportInstance implements Disposable {
         return metadataReport;
     }
 
-
-    private void checkInit() {
-        if (!init.get()) {
-            throw new IllegalStateException("the metadata report was not initialized.");
-        }
+    public boolean inited() {
+        return init.get();
     }
 
     @Override
     public void destroy() {
         metadataReports.forEach((_k, reporter) -> {
-//            reporter.destroy();
+            reporter.destroy();
         });
         metadataReports.clear();
     }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
index 4f18491..36b99d0 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
@@ -16,8 +16,6 @@
  */
 package org.apache.dubbo.metadata.report.support;
 
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
@@ -32,6 +30,9 @@ import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
 
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -75,9 +76,6 @@ import static org.apache.dubbo.metadata.report.support.Constants.RETRY_TIMES_KEY
 import static org.apache.dubbo.metadata.report.support.Constants.SYNC_REPORT_KEY;
 import static org.apache.dubbo.metadata.report.support.Constants.USER_HOME;
 
-/**
- *
- */
 public abstract class AbstractMetadataReport implements MetadataReport {
 
     protected final static String DEFAULT_ROOT = "dubbo";
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java
index 3134c9e..7f71705 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.metadata;
 
 import org.apache.dubbo.common.URL;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -36,40 +37,54 @@ import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SER
 class AbstractServiceNameMappingTest {
 
     private MockServiceNameMapping mapping = new MockServiceNameMapping();
+    private MockServiceNameMapping2 mapping2 = new MockServiceNameMapping2();
+
+    URL url = URL.valueOf("dubbo://127.0.0.1:21880/" + AbstractServiceNameMappingTest.class);
 
     @BeforeEach
     public void setUp() throws Exception {}
 
+    @AfterEach
+    public void clearup() throws Exception {
+        mapping.removeCachedMapping(ServiceNameMapping.buildMappingKey(url));
+    }
+
     @Test
     void testGetServices() {
-        URL url = URL.valueOf("dubbo://127.0.0.1:21880/" + AbstractServiceNameMappingTest.class);
         url = url.addParameter(PROVIDED_BY, "app1,app2");
         Set<String> services = mapping.getServices(url);
         Assertions.assertTrue(services.contains("app1"));
         Assertions.assertTrue(services.contains("app2"));
 
+        // check mapping cache works.
         url = url.removeParameter(PROVIDED_BY);
         services = mapping.getServices(url);
+        Assertions.assertTrue(services.contains("app1"));
+        Assertions.assertTrue(services.contains("app2"));
+
+        // remove mapping cache, check get() works.
+        mapping.removeCachedMapping(ServiceNameMapping.buildMappingKey(url));
+        services = mapping.getServices(url);
         Assertions.assertTrue(services.contains("remote-app1"));
         Assertions.assertTrue(services.contains("remote-app2"));
 
 
         Assertions.assertNotNull(mapping.getCachedMapping(url));
         Assertions.assertIterableEquals(mapping.getCachedMapping(url), services);
-
     }
 
     @Test
     public void testGetAndListener() {
-        URL url = URL.valueOf("dubbo://127.0.0.1:21880/" + AbstractServiceNameMappingTest.class);
         URL registryURL = URL.valueOf("registry://127.0.0.1:7777/test");
         registryURL = registryURL.addParameter(SUBSCRIBED_SERVICE_NAMES_KEY, "registry-app1");
 
-        Set<String> services = mapping.getAndListen(registryURL, url, null);
+        Set<String> services = mapping2.getAndListen(registryURL, url, null);
         Assertions.assertTrue(services.contains("registry-app1"));
 
-        mapping.enabled = true;
-        services = mapping.getAndListen(registryURL, url, new MappingListener() {
+        // remove mapping cache, check get() works.
+        mapping.removeCachedMapping(ServiceNameMapping.buildMappingKey(url));
+        mapping2.enabled = true;
+        services = mapping2.getAndListen(registryURL, url, new MappingListener() {
             @Override
             public void onEvent(MappingChangedEvent event) {
 
@@ -112,4 +127,32 @@ class AbstractServiceNameMappingTest {
         }
     }
 
+    private class MockServiceNameMapping2 extends AbstractServiceNameMapping {
+
+        public boolean enabled = false;
+
+        @Override
+        public Set<String> get(URL url) {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public Set<String> getAndListen(URL url, MappingListener mappingListener) {
+            if (!enabled) {
+                return Collections.emptySet();
+            }
+            return new HashSet<>(Arrays.asList("remote-app3"));
+        }
+
+        @Override
+        protected void removeListener(URL url, MappingListener mappingListener) {
+
+        }
+
+        @Override
+        public boolean map(URL url) {
+            return false;
+        }
+    }
+
 }
diff --git a/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/ClassFinder.java b/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/ClassFinder.java
index bf0f02c..c5c350e 100644
--- a/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/ClassFinder.java
+++ b/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/ClassFinder.java
@@ -16,7 +16,6 @@
  */
 package org.apache.dubbo.maven.plugin;
 
-
 import java.io.File;
 import java.net.JarURLConnection;
 import java.net.URL;
diff --git a/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/Test.java b/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/Test.java
index f5ab791..29fc800 100644
--- a/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/Test.java
+++ b/dubbo-native-plugin/src/main/java/org/apache/dubbo/maven/plugin/Test.java
@@ -19,10 +19,6 @@ package org.apache.dubbo.maven.plugin;
 
 import java.util.Set;
 
-/**
- * @Author goodjava@qq.com
- * @Date 2021/9/26 14:12
- */
 public class Test {
 
     public static void main(String[] args) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
index 812e570..dc2eb8b 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
@@ -48,25 +48,24 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery {
     protected volatile MetadataInfo metadataInfo;
     protected MetadataReport metadataReport;
     protected MetaCacheManager metaCacheManager;
+    protected URL registryURL;
 
     private ApplicationModel applicationModel;
 
-    public AbstractServiceDiscovery(ApplicationModel applicationModel) {
-        this(applicationModel.getApplicationName());
+    public AbstractServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        this(applicationModel.getApplicationName(), registryURL);
         this.applicationModel = applicationModel;
+
+        metadataReport = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class)
+            .getMetadataReport(registryURL.getParameter(REGISTRY_CLUSTER_KEY));
     }
 
-    public AbstractServiceDiscovery(String serviceName) {
+    public AbstractServiceDiscovery(String serviceName, URL registryURL) {
+        this.applicationModel = ApplicationModel.defaultModel();
+        this.registryURL = registryURL;
         this.serviceName = serviceName;
         this.metadataInfo = new MetadataInfo(serviceName);
-        this.metaCacheManager = new MetaCacheManager(AbstractServiceDiscovery.class.getSimpleName());
-    }
-
-    @Override
-    public final void initialize(URL registryURL) throws Exception {
-        doInitialize(registryURL);
-        String registryCluster = registryURL.getParameter(REGISTRY_CLUSTER_KEY);
-        metadataReport = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class).getMetadataReport(registryCluster);
+        this.metaCacheManager = new MetaCacheManager(getCacheNameSuffix());
     }
 
     public synchronized final void register() throws RuntimeException {
@@ -190,12 +189,15 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery {
         this.doRegister(serviceInstance);
     }
 
+    @Override
+    public URL getUrl() {
+        return registryURL;
+    }
+
     public abstract void doRegister(ServiceInstance serviceInstance) throws RuntimeException;
 
     public abstract void doUnregister();
 
-    public abstract void doInitialize(URL registryURL) throws Exception;
-
     public abstract void doDestroy() throws Exception;
 
     private ServiceInstance createServiceInstance() {
@@ -221,13 +223,29 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery {
     }
 
     protected void reportMetadata() {
-        SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
-        metadataReport.publishAppMetadata(identifier, metadataInfo);
+        if (metadataReport != null) {
+            SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
+            metadataReport.publishAppMetadata(identifier, metadataInfo);
+        }
     }
 
     protected void unReportMetadata() {
-        SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
-        metadataReport.unPublishAppMetadata(identifier, metadataInfo);
+        if (metadataReport != null) {
+            SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
+            metadataReport.unPublishAppMetadata(identifier, metadataInfo);
+        }
     }
 
+    private String getCacheNameSuffix() {
+        String name = this.getClass().getSimpleName();
+        int i = name.indexOf("ServiceDiscovery");
+        if (i != -1) {
+            name = name.substring(0, i);
+        }
+        URL url = this.getUrl();
+        if (url != null) {
+           return name.toLowerCase() + url.getBackupAddress();
+        }
+        return name.toLowerCase();
+    }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
index 9211990..a3c4428 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
@@ -270,7 +270,11 @@ public class DefaultServiceInstance implements ServiceInstance {
             if (entry.getKey().equals(EXPORTED_SERVICES_REVISION_PROPERTY_NAME)) {
                 continue;
             }
-            equals = equals && entry.getValue().equals(that.getMetadata().get(entry.getKey()));
+            if (entry.getValue() == null) {
+                equals = equals && (entry.getValue() == that.getMetadata().get(entry.getKey()));
+            } else {
+                equals = equals && entry.getValue().equals(that.getMetadata().get(entry.getKey()));
+            }
         }
 
         return equals;
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java
index ba5f7fc..fbbb32d 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java
@@ -495,7 +495,11 @@ public class InstanceAddressURL extends URL {
 
     @Override
     public ScopeModel getScopeModel() {
-        return RpcContext.getServiceContext().getConsumerUrl().getScopeModel();
+        URL consumerURL = RpcContext.getServiceContext().getConsumerUrl();
+        if (consumerURL == null) {
+            return null;
+        }
+        return consumerURL.getScopeModel();
     }
 
     @Override
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
index 182ccd0..9972e3c 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
@@ -18,19 +18,13 @@ package org.apache.dubbo.registry.client;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.lang.Prioritized;
-import org.apache.dubbo.common.utils.Page;
 import org.apache.dubbo.metadata.MetadataInfo;
 import org.apache.dubbo.registry.RegistryService;
 import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
 
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
-import static java.util.Collections.unmodifiableList;
-import static java.util.Collections.unmodifiableMap;
 import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_DELAY_NOTIFICATION_KEY;
 
 /**
@@ -38,22 +32,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_DELAY_N
  *
  */
 public interface ServiceDiscovery extends RegistryService, Prioritized {
-    /**
-     * Initializes the {@link ServiceDiscovery}
-     *
-     * @param registryURL the {@link URL url} to connect service registry
-     * @throws Exception If met with error
-     */
-    void initialize(URL registryURL) throws Exception;
-
-    /**
-     * Destroy the {@link ServiceDiscovery}
-     *
-     * @throws Exception If met with error
-     */
-    void destroy() throws Exception;
-
-    boolean isDestroy();
 
     void register() throws RuntimeException;
 
@@ -62,104 +40,13 @@ public interface ServiceDiscovery extends RegistryService, Prioritized {
     void unregister() throws RuntimeException;
 
     /**
-     * Get the default size of pagination query
-     *
-     * @return the default value is 100
-     */
-    default int getDefaultPageSize() {
-        return 100;
-    }
-
-    /**
      * Gets all service names
      *
      * @return non-null read-only {@link Set}
      */
     Set<String> getServices();
 
-    /**
-     * Gets all {@link ServiceInstance service instances} by the specified service name.
-     *
-     * @param serviceName the service name
-     * @return non-null {@link List}
-     * @throws NullPointerException if <code>serviceName</code> is <code>null</code>
-     */
-    default List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
-
-        List<ServiceInstance> allInstances = new LinkedList<>();
-
-        int offset = 0;
-
-        int pageSize = getDefaultPageSize();
-
-        Page<ServiceInstance> page = getInstances(serviceName, offset, pageSize);
-
-        allInstances.addAll(page.getData());
-
-        while (page.hasNext()) {
-            offset += page.getDataSize();
-            page = getInstances(serviceName, offset, pageSize);
-            allInstances.addAll(page.getData());
-        }
-
-        return unmodifiableList(allInstances);
-    }
-
-    /**
-     * Gets the {@link Page pagination} of {@link ServiceInstance service instances} by the specified service name.
-     * It's equal to {@link #getInstances(String, int, int, boolean)} with <code>healthyOnly == false</code>
-     *
-     * @param serviceName the service name
-     * @param offset      the offset of request , the number "0" indicates first page
-     * @param pageSize    the number of request, the {@link Integer#MAX_VALUE max value} indicates the range is unlimited
-     * @return non-null {@link Page} object
-     * @throws NullPointerException          if <code>serviceName</code> is <code>null</code>
-     * @throws IllegalArgumentException      if <code>offset</code> or <code>pageSize</code> is negative number
-     * @throws UnsupportedOperationException if not supported
-     */
-    default Page<ServiceInstance> getInstances(String serviceName, int offset, int pageSize) throws NullPointerException,
-            IllegalArgumentException {
-        return getInstances(serviceName, offset, pageSize, false);
-    }
-
-    /**
-     * Get the {@link Page pagination} of {@link ServiceInstance service instances} by the specified service name.
-     * If <code>healthyOnly == true</code>, filter healthy instances only.
-     *
-     * @param serviceName the service name
-     * @param offset      the offset of request , the number "0" indicates first page
-     * @param pageSize    the number of request, the {@link Integer#MAX_VALUE max value} indicates the range is unlimited
-     * @param healthyOnly if <code>true</code> , filter healthy instances only
-     * @return non-null {@link Page} object
-     * @throws NullPointerException          if <code>serviceName</code> is <code>null</code>
-     * @throws IllegalArgumentException      if <code>offset</code> or <code>pageSize</code> is negative number
-     * @throws UnsupportedOperationException if not supported
-     */
-    default Page<ServiceInstance> getInstances(String serviceName, int offset, int pageSize, boolean healthyOnly) throws
-            NullPointerException, IllegalArgumentException, UnsupportedOperationException {
-        throw new UnsupportedOperationException("Current implementation does not support pagination query method.");
-    }
-
-    /**
-     * batch-get all {@link ServiceInstance service instances} by the specified service names
-     *
-     * @param serviceNames the multiple service names
-     * @param offset       the offset of request , the number "0" indicates first page
-     * @param requestSize  the number of request, the {@link Integer#MAX_VALUE max value} indicates the range is unlimited
-     * @return non-null read-only {@link Map} whose key is the service name and value is
-     * the {@link Page pagination} of {@link ServiceInstance service instances}
-     * @throws NullPointerException          if <code>serviceName</code> is <code>null</code>
-     * @throws IllegalArgumentException      if <code>offset</code> or <code>requestSize</code> is negative number
-     * @throws UnsupportedOperationException if not supported
-     */
-    default Map<String, Page<ServiceInstance>> getInstances(Iterable<String> serviceNames, int offset, int requestSize) throws
-            NullPointerException, IllegalArgumentException {
-        Map<String, Page<ServiceInstance>> instances = new LinkedHashMap<>();
-        for (String serviceName : serviceNames) {
-            instances.put(serviceName, getInstances(serviceName, offset, requestSize));
-        }
-        return unmodifiableMap(instances);
-    }
+    List<ServiceInstance> getInstances(String serviceName) throws NullPointerException;
 
     default void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener)
             throws NullPointerException, IllegalArgumentException {
@@ -185,6 +72,15 @@ public interface ServiceDiscovery extends RegistryService, Prioritized {
 
     MetadataInfo getRemoteMetadata(String revision, ServiceInstance instance);
 
+    /**
+     * Destroy the {@link ServiceDiscovery}
+     *
+     * @throws Exception If met with error
+     */
+    void destroy() throws Exception;
+
+    boolean isDestroy();
+
     default URL getUrl() {
         return null;
     }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
index d4e2102..551fd55 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.registry.client;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.function.ThrowableAction;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
@@ -108,11 +107,8 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
      * @return non-null
      */
     protected ServiceDiscovery createServiceDiscovery(URL registryURL) {
-        ServiceDiscovery serviceDiscovery = getServiceDiscovery(registryURL);
-        final ThrowableAction throwableAction = () -> serviceDiscovery.initialize(registryURL.addParameter(INTERFACE_KEY, ServiceDiscovery.class.getName())
+        return getServiceDiscovery(registryURL.addParameter(INTERFACE_KEY, ServiceDiscovery.class.getName())
             .removeParameter(REGISTRY_TYPE_KEY));
-        execute(throwableAction);
-        return serviceDiscovery;
     }
 
     private List<SubscribedURLsSynthesizer> initSubscribedURLsSynthesizers() {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
index fe8e9a9..0394aa9 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
@@ -109,15 +109,21 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping {
         String serviceInterface = url.getServiceInterface();
         String registryCluster = getRegistryCluster(url);
         MetadataReport metadataReport = metadataReportInstance.getMetadataReport(registryCluster);
+        if (metadataReport == null) {
+            return Collections.emptySet();
+        }
         return metadataReport.getServiceAppMapping(serviceInterface, url);
     }
 
     @Override
     public Set<String> getAndListen(URL url, MappingListener mappingListener) {
         String serviceInterface = url.getServiceInterface();
-        // randomly pick one metadata report is ok for it's guaranteed each metadata report will have the same mapping content.
+        // randomly pick one metadata report is ok for it's guaranteed all metadata report will have the same mapping data.
         String registryCluster = getRegistryCluster(url);
         MetadataReport metadataReport = metadataReportInstance.getMetadataReport(registryCluster);
+        if (metadataReport == null) {
+            return Collections.emptySet();
+        }
         return metadataReport.getServiceAppMapping(serviceInterface, mappingListener, url);
     }
 
@@ -127,6 +133,9 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping {
         // randomly pick one metadata report is ok for it's guaranteed each metadata report will have the same mapping content.
         String registryCluster = getRegistryCluster(url);
         MetadataReport metadataReport = metadataReportInstance.getMetadataReport(registryCluster);
+        if (metadataReport == null) {
+            return;
+        }
         metadataReport.removeServiceAppMappingListener(serviceInterface, mappingListener);
     }
 
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
index f554f17..4bfa752 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
@@ -65,7 +65,10 @@ public class MetadataUtils {
     }
 
     public static void publishServiceDefinition(ServiceDescriptor serviceDescriptor, ApplicationModel applicationModel) {
-        checkRemoteConfigured(applicationModel);
+        if (getMetadataReports(applicationModel).size() == 0) {
+            String msg = "Remote Metadata Report Server not hasn't been configured or unavailable . Unable to get Metadata from remote!";
+            logger.warn(msg);
+        }
 
         String serviceName = serviceDescriptor.getServiceName();
         FullServiceDefinition serviceDefinition = serviceDescriptor.getServiceDefinition(serviceName);
@@ -151,7 +154,6 @@ public class MetadataUtils {
                 MetadataUtils.destroyMetadataServiceProxy(instance);
             }
         } catch (Exception e) {
-            logger.error("Failed to load service metadata, meta type is " + metadataType, e);
             metadataInfo = null;
         }
 
@@ -178,14 +180,6 @@ public class MetadataUtils {
         return metadataReport.getAppMetadata(identifier, params);
     }
 
-    private static void checkRemoteConfigured(ApplicationModel applicationModel) {
-        if (getMetadataReports(applicationModel).size() == 0) {
-            String msg = "Remote Metadata Report Server not hasn't been configured or unavailable . Unable to get Metadata from remote!";
-            logger.error(msg);
-            throw new IllegalStateException(msg);
-        }
-    }
-
     private static Map<String, MetadataReport> getMetadataReports(ApplicationModel applicationModel) {
         return applicationModel.getBeanFactory().getBean(MetadataReportInstance.class).getMetadataReports(false);
     }
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscovery.java
index f921cf5..42eb492 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscovery.java
@@ -21,20 +21,17 @@ import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 public class MockServiceDiscovery extends AbstractServiceDiscovery {
-    public MockServiceDiscovery(ApplicationModel applicationModel) {
-        super(applicationModel);
+    public MockServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        super(applicationModel, registryURL);
     }
 
-    public MockServiceDiscovery(String serviceName) {
-        super(serviceName);
-    }
-
-    @Override
-    public void doInitialize(URL registryURL) throws Exception {
-
+    public MockServiceDiscovery(String serviceName, URL registryURL) {
+        super(serviceName, registryURL);
     }
 
     @Override
@@ -61,4 +58,9 @@ public class MockServiceDiscovery extends AbstractServiceDiscovery {
     public Set<String> getServices() {
         return null;
     }
+
+    @Override
+    public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
+        return Collections.emptyList();
+    }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscoveryFactory.java
index cb12c4e..5b67311 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/support/MockServiceDiscoveryFactory.java
@@ -23,6 +23,6 @@ import org.apache.dubbo.registry.client.ServiceDiscovery;
 public class MockServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
     @Override
     protected ServiceDiscovery createDiscovery(URL registryURL) {
-        return new MockServiceDiscovery(applicationModel.getApplicationName());
+        return new MockServiceDiscovery(applicationModel, registryURL);
     }
 }
diff --git a/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscovery.java b/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscovery.java
index 7530201..d5ba16b 100644
--- a/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscovery.java
@@ -22,25 +22,19 @@ import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 /**
  * TODO: make multicast protocol support Service Discovery
  */
 public class MulticastServiceDiscovery extends AbstractServiceDiscovery {
-    private URL registryURL;
-
-    public MulticastServiceDiscovery(ApplicationModel applicationModel) {
-        super(applicationModel);
-    }
-
-    public MulticastServiceDiscovery(String serviceName) {
-        super(serviceName);
+    public MulticastServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        super(applicationModel, registryURL);
     }
 
-    @Override
-    public void doInitialize(URL registryURL) throws Exception {
-        this.registryURL = registryURL;
+    public MulticastServiceDiscovery(String serviceName, URL registryURL) {
+        super(serviceName, registryURL);
     }
 
     @Override
@@ -67,6 +61,11 @@ public class MulticastServiceDiscovery extends AbstractServiceDiscovery {
     }
 
     @Override
+    public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
+        return null;
+    }
+
+    @Override
     public URL getUrl() {
         return registryURL;
     }
diff --git a/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscoveryFactory.java
index 4d3de8c..324298a 100644
--- a/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastServiceDiscoveryFactory.java
@@ -23,6 +23,6 @@ import org.apache.dubbo.registry.client.ServiceDiscovery;
 public class MulticastServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
     @Override
     protected ServiceDiscovery createDiscovery(URL registryURL) {
-        return new MulticastServiceDiscovery(applicationModel);
+        return new MulticastServiceDiscovery(applicationModel, registryURL);
     }
 }
diff --git a/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java b/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
index 7a36ec4..361014c 100644
--- a/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
@@ -18,8 +18,6 @@ package org.apache.dubbo.registry.multiple;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.constants.CommonConstants;
-import org.apache.dubbo.common.utils.DefaultPage;
-import org.apache.dubbo.common.utils.Page;
 import org.apache.dubbo.metadata.MetadataInfo;
 import org.apache.dubbo.registry.NotifyListener;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
@@ -42,12 +40,10 @@ public class MultipleServiceDiscovery implements ServiceDiscovery {
     private static final String SERVICE = "service";
     private final Map<String, ServiceDiscovery> serviceDiscoveries = new ConcurrentHashMap<>();
     private URL registryURL;
-    private ServiceInstance serviceInstance;
     private String applicationName;
     private volatile boolean isDestroy;
 
-    @Override
-    public void initialize(URL registryURL) throws Exception {
+    public MultipleServiceDiscovery(URL registryURL) {
         this.registryURL = registryURL;
         this.applicationName = registryURL.getApplication();
 
@@ -57,7 +53,6 @@ public class MultipleServiceDiscovery implements ServiceDiscovery {
                 URL url = URL.valueOf(registryURL.getParameter(key)).addParameter(CommonConstants.APPLICATION_KEY, applicationName)
                     .addParameter(REGISTRY_TYPE, SERVICE);
                 ServiceDiscovery serviceDiscovery = ServiceDiscoveryFactory.getExtension(url).getServiceDiscovery(url);
-                serviceDiscovery.initialize(url);
                 serviceDiscoveries.put(key, serviceDiscovery);
             }
         }
@@ -124,19 +119,6 @@ public class MultipleServiceDiscovery implements ServiceDiscovery {
     }
 
     @Override
-    public Page<ServiceInstance> getInstances(String serviceName, int offset, int pageSize, boolean healthyOnly)
-        throws NullPointerException, IllegalArgumentException, UnsupportedOperationException {
-
-        List<ServiceInstance> serviceInstanceList = new ArrayList<>();
-        for (ServiceDiscovery serviceDiscovery : serviceDiscoveries.values()) {
-            Page<ServiceInstance> serviceInstancePage = serviceDiscovery.getInstances(serviceName, offset, pageSize, healthyOnly);
-            serviceInstanceList.addAll(serviceInstancePage.getData());
-        }
-
-        return new DefaultPage<>(offset, pageSize, serviceInstanceList, serviceInstanceList.size());
-    }
-
-    @Override
     public Set<String> getServices() {
         Set<String> services = new HashSet<>();
         for (ServiceDiscovery serviceDiscovery : serviceDiscoveries.values()) {
@@ -147,7 +129,7 @@ public class MultipleServiceDiscovery implements ServiceDiscovery {
 
     @Override
     public ServiceInstance getLocalInstance() {
-        return serviceInstance;
+        return null;
     }
 
     @Override
diff --git a/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryFactory.java
index 1eb4dc8..5f2fdfa 100644
--- a/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryFactory.java
@@ -23,6 +23,6 @@ import org.apache.dubbo.registry.client.ServiceDiscovery;
 public class MultipleServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
     @Override
     protected ServiceDiscovery createDiscovery(URL registryURL) {
-        return new MultipleServiceDiscovery();
+        return new MultipleServiceDiscovery(registryURL);
     }
 }
diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
index 1c782ac..9a8b2a7 100644
--- a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
@@ -55,20 +55,9 @@ public class NacosServiceDiscovery extends AbstractServiceDiscovery {
 
     private NacosNamingServiceWrapper namingService;
 
-    private URL registryURL;
-
-    public NacosServiceDiscovery(ApplicationModel applicationModel) {
-        super(applicationModel);
-    }
-
-    public NacosServiceDiscovery(String serviceName) {
-        super(serviceName);
-    }
-
-    @Override
-    public void doInitialize(URL registryURL) throws Exception {
+    public NacosServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        super(applicationModel, registryURL);
         this.namingService = createNamingService(registryURL);
-        this.registryURL = registryURL;
     }
 
     @Override
diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java
index 72bc41f..56e1c26 100644
--- a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryFactory.java
@@ -24,7 +24,7 @@ public class NacosServiceDiscoveryFactory extends AbstractServiceDiscoveryFactor
 
     @Override
     protected ServiceDiscovery createDiscovery(URL registryURL) {
-        return new NacosServiceDiscovery(applicationModel);
+        return new NacosServiceDiscovery(applicationModel, registryURL);
     }
 
 }
diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
index 1282a9c..23b15d8 100644
--- a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceDiscoveryTest.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.registry.nacos;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
@@ -71,10 +72,14 @@ public class NacosServiceDiscoveryTest {
 
     @BeforeEach
     public void init() throws Exception {
+        ApplicationModel applicationModel = ApplicationModel.defaultModel();
+        applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig(SERVICE_NAME));
+
         this.registryUrl = URL.valueOf("nacos://127.0.0.1:" + NetUtils.getAvailablePort());
-        registryUrl.setScopeModel(ApplicationModel.defaultModel());
+        registryUrl.setScopeModel(applicationModel);
 
-        this.nacosServiceDiscovery = new NacosServiceDiscovery(SERVICE_NAME);
+//        this.nacosServiceDiscovery = new NacosServiceDiscovery(SERVICE_NAME, registryUrl);
+        this.nacosServiceDiscovery = new NacosServiceDiscovery(applicationModel, registryUrl);
         Field namingService = nacosServiceDiscovery.getClass().getDeclaredField("namingService");
         namingService.setAccessible(true);
         namingServiceWrapper = mock(NacosNamingServiceWrapper.class);
diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java
index 9f2ee17..1a3a335 100644
--- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java
@@ -21,8 +21,6 @@ import org.apache.dubbo.common.function.ThrowableConsumer;
 import org.apache.dubbo.common.function.ThrowableFunction;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.DefaultPage;
-import org.apache.dubbo.common.utils.Page;
 import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
@@ -35,9 +33,7 @@ import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.api.CuratorWatcher;
 import org.apache.zookeeper.KeeperException;
 
-import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -59,8 +55,6 @@ public class ZookeeperServiceDiscovery extends AbstractServiceDiscovery {
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
-    private URL registryURL;
-
     private CuratorFramework curatorFramework;
 
     private String rootPath;
@@ -72,26 +66,16 @@ public class ZookeeperServiceDiscovery extends AbstractServiceDiscovery {
      */
     private final Map<String, ZookeeperServiceDiscoveryChangeWatcher> watcherCaches = new ConcurrentHashMap<>();
 
-    public ZookeeperServiceDiscovery(ApplicationModel applicationModel) {
-        super(applicationModel);
-    }
-
-    public ZookeeperServiceDiscovery(String serviceName) {
-        super(serviceName);
-    }
-
-    @Override
-    public void doInitialize(URL registryURL) throws Exception {
-        this.registryURL = registryURL;
-        this.curatorFramework = buildCuratorFramework(registryURL);
-        this.rootPath = ROOT_PATH.getParameterValue(registryURL);
-        this.serviceDiscovery = buildServiceDiscovery(curatorFramework, rootPath);
-        this.serviceDiscovery.start();
-    }
-
-    @Override
-    public URL getUrl() {
-        return registryURL;
+    public ZookeeperServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
+        super(applicationModel, registryURL);
+        try {
+            this.curatorFramework = buildCuratorFramework(registryURL);
+            this.rootPath = ROOT_PATH.getParameterValue(registryURL);
+            this.serviceDiscovery = buildServiceDiscovery(curatorFramework, rootPath);
+            this.serviceDiscovery.start();
+        } catch (Exception e) {
+            throw new IllegalStateException("Create zookeeper service discovery failed.", e);
+        }
     }
 
     @Override
@@ -127,48 +111,6 @@ public class ZookeeperServiceDiscovery extends AbstractServiceDiscovery {
     }
 
     @Override
-    public Page<ServiceInstance> getInstances(String serviceName, int offset, int pageSize, boolean healthyOnly) {
-        String path = buildServicePath(serviceName);
-
-        return execute(path, p -> {
-
-            List<ServiceInstance> serviceInstances = new LinkedList<>();
-
-            int totalSize = 0;
-            try {
-                List<String> serviceIds = new LinkedList<>(curatorFramework.getChildren().forPath(p));
-
-                totalSize = serviceIds.size();
-
-                Iterator<String> iterator = serviceIds.iterator();
-
-                for (int i = 0; i < offset; i++) {
-                    if (iterator.hasNext()) { // remove the elements from 0 to offset
-                        iterator.next();
-                        iterator.remove();
-                    }
-                }
-
-                for (int i = 0; i < pageSize; i++) {
-                    if (iterator.hasNext()) {
-                        String serviceId = iterator.next();
-                        ServiceInstance serviceInstance = build(registryURL, serviceDiscovery.queryForInstance(serviceName, serviceId));
-                        serviceInstances.add(serviceInstance);
-                    }
-                }
-
-                if (healthyOnly) {
-                    serviceInstances.removeIf(instance -> !instance.isHealthy());
-                }
-            } catch (KeeperException.NoNodeException e) {
-                logger.warn(p + " path not exist.", e);
-            }
-
-            return new DefaultPage<>(offset, pageSize, serviceInstances, totalSize);
-        });
-    }
-
-    @Override
     public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener)
         throws NullPointerException, IllegalArgumentException {
         listener.getServiceNames().forEach(serviceName -> registerServiceWatcher(serviceName, listener));
diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryFactory.java
index 47c8fbb..7ce7f73 100644
--- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryFactory.java
@@ -24,6 +24,6 @@ public class ZookeeperServiceDiscoveryFactory extends AbstractServiceDiscoveryFa
 
     @Override
     protected ServiceDiscovery createDiscovery(URL registryURL) {
-        return new ZookeeperServiceDiscovery(applicationModel);
+        return new ZookeeperServiceDiscovery(applicationModel, registryURL);
     }
 }
diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
index 97e471f..183a841 100644
--- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
+++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/util/CuratorFrameworkUtils.java
@@ -85,8 +85,7 @@ public abstract class CuratorFrameworkUtils {
     }
 
 
-    public static List<ServiceInstance> build(URL registryUrl, Collection<org.apache.curator.x.discovery.ServiceInstance<ZookeeperInstance>>
-        instances) {
+    public static List<ServiceInstance> build(URL registryUrl, Collection<org.apache.curator.x.discovery.ServiceInstance<ZookeeperInstance>> instances) {
         return instances.stream().map((i)->build(registryUrl, i)).collect(Collectors.toList());
     }
 
diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/test/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryTest.java b/dubbo-registry/dubbo-registry-zookeeper/src/test/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryTest.java
index 19a6b6e..44f143b 100644
--- a/dubbo-registry/dubbo-registry-zookeeper/src/test/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryTest.java
+++ b/dubbo-registry/dubbo-registry-zookeeper/src/test/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscoveryTest.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.registry.zookeeper;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
@@ -64,9 +65,10 @@ public class ZookeeperServiceDiscoveryTest {
         zkServer.start();
 
         this.registryUrl = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort);
-        registryUrl.setScopeModel(ApplicationModel.defaultModel());
-        this.discovery = new ZookeeperServiceDiscovery(SERVICE_NAME);
-        this.discovery.initialize(registryUrl);
+        ApplicationModel applicationModel = ApplicationModel.defaultModel();
+        applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig(SERVICE_NAME));
+        registryUrl.setScopeModel(applicationModel);
+        this.discovery = new ZookeeperServiceDiscovery(applicationModel, registryUrl);
     }
 
     @AfterEach
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
index 50110d7..3545e6a 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.serialize.support.SerializableClassRegistry;
 import org.apache.dubbo.common.serialize.support.SerializationOptimizer;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.ConcurrentHashSet;
 import org.apache.dubbo.common.utils.NetUtils;
@@ -638,10 +639,11 @@ public class DubboProtocol extends AbstractProtocol {
 
         ExchangeClient client;
         try {
+            // Replace InstanceAddressURL with ServiceConfigURL.
+            url = new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), url.getParameters());
             // connection should be lazy
             if (url.getParameter(LAZY_CONNECT_KEY, false)) {
                 client = new LazyConnectExchangeClient(url, requestHandler);
-
             } else {
                 client = Exchangers.connect(url, requestHandler);
             }
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java
index a825ccd..c3abca2 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java
@@ -20,7 +20,6 @@ import org.apache.dubbo.common.Parameters;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.url.component.ServiceConfigURL;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.RemotingException;
@@ -62,8 +61,7 @@ final class LazyConnectExchangeClient implements ExchangeClient {
 
     public LazyConnectExchangeClient(URL url, ExchangeHandler requestHandler) {
         // lazy connect, need set send.reconnect = true, to avoid channel bad status.
-        this.url = new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), url.getParameters())
-            .addParameter(SEND_RECONNECT_KEY, Boolean.TRUE.toString());
+        this.url = url.addParameter(SEND_RECONNECT_KEY, Boolean.TRUE.toString());
         this.requestHandler = requestHandler;
         this.initialState = url.getParameter(LAZY_CONNECT_INITIAL_STATE_KEY, DEFAULT_LAZY_CONNECT_INITIAL_STATE);
         this.requestWithWarning = url.getParameter(LAZY_REQUEST_WITH_WARNING_KEY, DEFAULT_LAZY_REQUEST_WITH_WARNING);