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 2019/08/09 02:40:30 UTC

[dubbo] branch cloud-native updated (4a3f8ab -> 05ce087)

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

liujun pushed a change to branch cloud-native
in repository https://gitbox.apache.org/repos/asf/dubbo.git.


    from 4a3f8ab  modify metadata
     new 550b404  Change how service instance is created.
     new b7b34b6  Merge branch 'cloud-native' of https://github.com/apache/dubbo into cloud-native
     new 2245cf7  Introduce ProtocolServer to distinguish from RemotingServer
     new 05ce087  Merge remote-tracking branch 'origin/cloud-native' into cloud-native

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 dubbo-bootstrap/pom.xml                            |   7 +
 .../org/apache/dubbo/bootstrap/DubboBootstrap.java | 153 +++++++++++++--------
 .../bootstrap/DubboServiceProviderBootstrap.java   |   4 +-
 .../DefaultGovernanceRuleRepositoryImpl.java       |  52 +------
 .../governance/GovernanceRuleRepository.java       |  94 +++++++++++++
 .../dubbo/rpc/cluster/router/AbstractRouter.java   |  13 +-
 .../cluster/router/condition/config/AppRouter.java |   5 +-
 .../router/condition/config/AppRouterFactory.java  |   3 +-
 .../router/condition/config/ListenableRouter.java  |   8 +-
 .../router/condition/config/ServiceRouter.java     |   4 +-
 .../condition/config/ServiceRouterFactory.java     |   3 +-
 .../dubbo/rpc/cluster/router/tag/TagRouter.java    |  10 +-
 .../rpc/cluster/router/tag/TagRouterFactory.java   |   3 +-
 ...rpc.cluster.governance.GovernanceRuleRepository |   1 +
 .../apache/dubbo/common/config/Configuration.java  |  49 +++++++
 .../configcenter/AbstractDynamicConfiguration.java |   5 -
 .../config/configcenter/DynamicConfiguration.java  |  26 ----
 .../file/FileSystemDynamicConfiguration.java       |   5 -
 .../configcenter/nop/NopDynamicConfiguration.java  |   6 -
 .../wrapper/CompositeDynamicConfiguration.java     |   7 +-
 .../file/FileSystemDynamicConfigurationTest.java   |   2 +-
 .../apache/dubbo/config/AbstractServiceConfig.java |   2 +-
 .../org/apache/dubbo/config/RegistryConfig.java    |  32 ++++-
 .../dubbo/config/builders/ConfigCenterBuilder.java |   1 -
 .../apache/dubbo/config/context/ConfigManager.java |   2 +-
 .../ConfigurableMetadataServiceExporter.java       |   1 +
 .../dubbo/config/DubboProviderBootstrap.java       |   5 +-
 .../org/apache/dubbo/config/mock/MockProtocol.java |   8 ++
 .../apache/dubbo/config/mock/MockProtocol2.java    |   8 ++
 .../apache/dubbo/config/mock/MockTransporter.java  |   6 +-
 .../src/main/resources/META-INF/compat/dubbo.xsd   |  10 ++
 .../src/main/resources/META-INF/dubbo.xsd          |  10 ++
 .../support/apollo/ApolloDynamicConfiguration.java |   2 +-
 .../consul/ConsulDynamicConfiguration.java         |  15 +-
 .../support/etcd/EtcdDynamicConfiguration.java     |  12 +-
 .../support/nacos/NacosDynamicConfiguration.java   |   5 -
 .../zookeeper/ZookeeperDynamicConfiguration.java   |  10 --
 .../dubbo/metadata/WritableMetadataService.java    |   1 +
 .../dubbo/qos/protocol/QosProtocolWrapper.java     |   7 +
 .../client/AbstractServiceDiscoveryFactory.java    |  71 ++++++++++
 .../EventPublishingServiceDiscoveryFactory.java    |  47 -------
 .../registry/client/ServiceDiscoveryFactory.java   |  17 +--
 ...ExportedServicesRevisionMetadataCustomizer.java |   5 +-
 ...MetadataServiceURLParamsMetadataCustomizer.java |   5 +-
 .../integration/AbstractConfiguratorListener.java  |   8 +-
 .../registry/integration/RegistryDirectory.java    |   3 +-
 .../registry/integration/RegistryProtocol.java     |  11 +-
 .../registry/support/AbstractRegistryFactory.java  |   1 -
 .../registry/support/ServiceOrientedRegistry.java  |   5 +-
 ...e.dubbo.registry.client.ServiceDiscoveryFactory |   1 -
 .../client/InMemoryServiceDiscoveryFactory.java    |   4 +-
 .../client/ServiceDiscoveryFactoryTest.java        |  55 --------
 .../registry/etcd/EtcdServiceDiscoveryFactory.java |   6 +-
 .../nacos/NacosServiceDiscoveryFactory.java        |   5 +-
 .../ZookeeperServiceDiscoveryFactory.java          |   5 +-
 .../java/org/apache/dubbo/remoting/Channel.java    |   4 +-
 .../java/org/apache/dubbo/remoting/Endpoint.java   |   2 +-
 .../remoting/{Server.java => RemotingServer.java}  | 116 ++++++++--------
 .../org/apache/dubbo/remoting/Transporter.java     |   2 +-
 .../org/apache/dubbo/remoting/Transporters.java    |   4 +-
 .../dubbo/remoting/exchange/ExchangeServer.java    |   4 +-
 .../support/header/HeaderExchangeServer.java       |   8 +-
 .../dubbo/remoting/transport/AbstractServer.java   |   8 +-
 .../dubbo/remoting/transport/ServerDelegate.java   |  12 +-
 .../transport/grizzly/GrizzlyTransporter.java      |   4 +-
 .../org/apache/dubbo/remoting/http/HttpServer.java |   3 +-
 .../remoting/http/support/AbstractHttpServer.java  |  48 +++++++
 .../remoting/transport/mina/MinaTransporter.java   |   4 +-
 .../remoting/transport/netty/NettyServer.java      |   4 +-
 .../remoting/transport/netty/NettyTransporter.java |   4 +-
 .../transport/netty/ClientReconnectTest.java       |   8 +-
 .../remoting/transport/netty/NettyClientTest.java  |   6 +-
 .../remoting/transport/netty4/NettyServer.java     |   4 +-
 .../transport/netty4/NettyTransporter.java         |   4 +-
 .../transport/netty4/ClientReconnectTest.java      |   8 +-
 .../transport/netty4/NettyTransporterTest.java     |   4 +-
 .../java/org/apache/dubbo/remoting/p2p/Peer.java   |   4 +-
 .../exchange/support/AbstractExchangeGroup.java    |   4 +-
 .../dubbo/remoting/p2p/support/AbstractGroup.java  |   8 +-
 .../dubbo/remoting/p2p/support/ServerPeer.java     |   4 +-
 .../main/java/org/apache/dubbo/rpc/Protocol.java   |   9 ++
 .../java/org/apache/dubbo/rpc/ProtocolServer.java  |  39 +++---
 .../dubbo/rpc/protocol/AbstractProtocol.java       |  12 ++
 .../dubbo/rpc/protocol/AbstractProxyProtocol.java  |  38 +++++
 .../dubbo/rpc/protocol/ProtocolFilterWrapper.java  |   6 +
 .../rpc/protocol/ProtocolListenerWrapper.java      |   9 +-
 .../dubbo/rpc/protocol/dubbo/DubboProtocol.java    |  22 ++-
 .../rpc/protocol/dubbo/DubboProtocolServer.java    |  46 ++++---
 .../protocol/dubbo/status/ServerStatusChecker.java |  10 +-
 .../protocol/dubbo/telnet/PortTelnetHandler.java   |  12 +-
 .../rpc/protocol/dubbo/support/ProtocolUtils.java  |   8 +-
 .../rpc/protocol/hessian/HessianProtocol.java      |  21 ++-
 .../dubbo/rpc/protocol/http/HttpProtocol.java      |  14 +-
 .../rpc/protocol/jsonrpc/JsonRpcProtocol.java      |  21 ++-
 ...RestServer.java => BaseRestProtocolServer.java} |  14 +-
 ...ttpServer.java => DubboHttpProtocolServer.java} |   6 +-
 ...ttyServer.java => NettyRestProtocolServer.java} |   6 +-
 .../dubbo/rpc/protocol/rest/RestProtocol.java      |  17 ++-
 .../{RestServer.java => RestProtocolServer.java}   |   4 +-
 .../dubbo/rpc/protocol/rest/RestServerFactory.java |   6 +-
 .../dubbo/rpc/protocol/thrift/ThriftProtocol.java  |  58 ++++++--
 .../protocol/webservice/WebServiceProtocol.java    |  15 +-
 .../xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java    |  15 +-
 103 files changed, 907 insertions(+), 628 deletions(-)
 copy dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java => dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java (53%)
 create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
 create mode 100644 dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository
 create mode 100644 dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java
 delete mode 100644 dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/EventPublishingServiceDiscoveryFactory.java
 delete mode 100644 dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
 delete mode 100644 dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactoryTest.java
 rename dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/{Server.java => RemotingServer.java} (92%)
 copy dubbo-compatible/src/test/java/org/apache/dubbo/rpc/cluster/NewRouter.java => dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java (60%)
 copy dubbo-compatible/src/test/java/org/apache/dubbo/rpc/cluster/NewRouter.java => dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java (53%)
 rename dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/{BaseRestServer.java => BaseRestProtocolServer.java} (90%)
 rename dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/{DubboHttpServer.java => DubboHttpProtocolServer.java} (96%)
 rename dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/{NettyServer.java => NettyRestProtocolServer.java} (96%)
 rename dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/{RestServer.java => RestProtocolServer.java} (91%)


[dubbo] 03/04: Introduce ProtocolServer to distinguish from RemotingServer

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2245cf70bc89c229a387fd9aa59339bdb947f8d6
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri Aug 9 10:36:28 2019 +0800

    Introduce ProtocolServer to distinguish from RemotingServer
---
 .../org/apache/dubbo/bootstrap/DubboBootstrap.java |  1 +
 .../DefaultGovernanceRuleRepositoryImpl.java       | 52 ++----------
 .../governance/GovernanceRuleRepository.java       | 94 ++++++++++++++++++++++
 .../dubbo/rpc/cluster/router/AbstractRouter.java   | 13 ++-
 .../cluster/router/condition/config/AppRouter.java |  5 +-
 .../router/condition/config/AppRouterFactory.java  |  3 +-
 .../router/condition/config/ListenableRouter.java  |  8 +-
 .../router/condition/config/ServiceRouter.java     |  4 +-
 .../condition/config/ServiceRouterFactory.java     |  3 +-
 .../dubbo/rpc/cluster/router/tag/TagRouter.java    | 10 +--
 .../rpc/cluster/router/tag/TagRouterFactory.java   |  3 +-
 ...rpc.cluster.governance.GovernanceRuleRepository |  1 +
 .../apache/dubbo/common/config/Configuration.java  | 49 +++++++++++
 .../configcenter/AbstractDynamicConfiguration.java |  5 --
 .../config/configcenter/DynamicConfiguration.java  | 26 ------
 .../file/FileSystemDynamicConfiguration.java       |  5 --
 .../configcenter/nop/NopDynamicConfiguration.java  |  6 --
 .../wrapper/CompositeDynamicConfiguration.java     |  5 --
 .../file/FileSystemDynamicConfigurationTest.java   |  2 +-
 .../support/apollo/ApolloDynamicConfiguration.java |  2 +-
 .../consul/ConsulDynamicConfiguration.java         | 15 ++--
 .../support/etcd/EtcdDynamicConfiguration.java     | 12 +--
 .../support/nacos/NacosDynamicConfiguration.java   |  5 --
 .../zookeeper/ZookeeperDynamicConfiguration.java   | 10 ---
 .../dubbo/qos/protocol/QosProtocolWrapper.java     |  7 ++
 .../integration/AbstractConfiguratorListener.java  |  8 +-
 .../registry/integration/RegistryDirectory.java    |  3 +-
 .../registry/integration/RegistryProtocol.java     |  5 +-
 .../java/org/apache/dubbo/rpc/ProtocolServer.java  |  5 +-
 .../dubbo/rpc/protocol/AbstractProxyProtocol.java  |  2 +-
 .../rpc/protocol/dubbo/DubboProtocolServer.java    |  2 +-
 .../rpc/protocol/rest/BaseRestProtocolServer.java  | 12 +++
 ...ttpServer.java => DubboHttpProtocolServer.java} |  4 +-
 .../dubbo/rpc/protocol/rest/RestProtocol.java      |  1 +
 .../dubbo/rpc/protocol/rest/RestServerFactory.java |  2 +-
 .../dubbo/rpc/protocol/thrift/ThriftProtocol.java  |  2 +-
 36 files changed, 224 insertions(+), 168 deletions(-)

diff --git a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
index fbc523a..005f11d 100644
--- a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
+++ b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
@@ -59,6 +59,7 @@ import org.apache.dubbo.rpc.ProtocolServer;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java
similarity index 53%
copy from dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
copy to dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java
index 7940101..64ddb02 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java
@@ -14,67 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.config.configcenter.nop;
+package org.apache.dubbo.rpc.cluster.governance;
 
-import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 
-import java.util.SortedSet;
+public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleRepository {
 
-import static java.util.Collections.emptySortedSet;
-
-/**
- * The default extension of {@link DynamicConfiguration}. If user does not specify a config centre, or specifies one
- * that is not a valid extension, it will default to this one.
- */
-@Deprecated
-public class NopDynamicConfiguration implements DynamicConfiguration {
-
-    public NopDynamicConfiguration(URL url) {
-        // no-op
-    }
-
-    @Override
-    public Object getInternalProperty(String key) {
-        return null;
-    }
+    private DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
 
     @Override
     public void addListener(String key, String group, ConfigurationListener listener) {
-        // no-op
+        dynamicConfiguration.addListener(key, group, listener);
     }
 
     @Override
     public void removeListener(String key, String group, ConfigurationListener listener) {
-        // no-op
-    }
-
-    @Override
-    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
-        // no-op
-        return null;
+        dynamicConfiguration.removeListener(key, group, listener);
     }
 
     @Override
     public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        // no-op
-        return null;
-    }
-
-    /**
-     * @since 2.7.4
-     */
-    @Override
-    public boolean publishConfig(String key, String group, String content) {
-        return true;
-    }
-
-    /**
-     * @since 2.7.4
-     */
-    @Override
-    public SortedSet<String> getConfigKeys(String group) {
-        return emptySortedSet();
+        return dynamicConfiguration.getConfig(key, group, timeout);
     }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
new file mode 100644
index 0000000..4391cba
--- /dev/null
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/GovernanceRuleRepository.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.cluster.governance;
+
+import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
+import org.apache.dubbo.common.extension.SPI;
+
+/**
+ *
+ */
+@SPI("default")
+public interface GovernanceRuleRepository {
+
+    String DEFAULT_GROUP = "dubbo";
+
+    /**
+     * {@link #addListener(String, String, ConfigurationListener)}
+     *
+     * @param key      the key to represent a configuration
+     * @param listener configuration listener
+     */
+    default void addListener(String key, ConfigurationListener listener) {
+        addListener(key, DEFAULT_GROUP, listener);
+    }
+
+
+    /**
+     * {@link #removeListener(String, String, ConfigurationListener)}
+     *
+     * @param key      the key to represent a configuration
+     * @param listener configuration listener
+     */
+    default void removeListener(String key, ConfigurationListener listener) {
+        removeListener(key, DEFAULT_GROUP, listener);
+    }
+
+    /**
+     * Register a configuration listener for a specified key
+     * The listener only works for service governance purpose, so the target group would always be the value user
+     * specifies at startup or 'dubbo' by default. This method will only register listener, which means it will not
+     * trigger a notification that contains the current value.
+     *
+     * @param key      the key to represent a configuration
+     * @param group    the group where the key belongs to
+     * @param listener configuration listener
+     */
+    void addListener(String key, String group, ConfigurationListener listener);
+
+    /**
+     * Stops one listener from listening to value changes in the specified key.
+     *
+     * @param key      the key to represent a configuration
+     * @param group    the group where the key belongs to
+     * @param listener configuration listener
+     */
+    void removeListener(String key, String group, ConfigurationListener listener);
+
+    /**
+     * Get the governance rule mapped to the given key and the given group
+     *
+     * @param key   the key to represent a configuration
+     * @param group the group where the key belongs to
+     * @return target configuration mapped to the given key and the given group
+     */
+    default String getRule(String key, String group) {
+        return getRule(key, group, -1L);
+    }
+
+    /**
+     * Get the governance rule mapped to the given key and the given group. If the
+     * rule fails to return after timeout exceeds, IllegalStateException will be thrown.
+     *
+     * @param key     the key to represent a configuration
+     * @param group   the group where the key belongs to
+     * @param timeout timeout value for fetching the target config
+     * @return target configuration mapped to the given key and the given group, IllegalStateException will be thrown
+     * if timeout exceeds.
+     */
+    String getRule(String key, String group, long timeout) throws IllegalStateException;
+}
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
index b848cb1..e5809b0 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
@@ -17,18 +17,19 @@
 package org.apache.dubbo.rpc.cluster.router;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.rpc.cluster.Router;
+import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
 
 public abstract class AbstractRouter implements Router {
     protected int priority = DEFAULT_PRIORITY;
     protected boolean force = false;
     protected URL url;
 
-    protected DynamicConfiguration configuration;
+    protected GovernanceRuleRepository ruleRepository;
 
-    public AbstractRouter(DynamicConfiguration configuration, URL url) {
-        this.configuration = configuration;
+    public AbstractRouter(URL url) {
+        this.ruleRepository = ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
         this.url = url;
     }
 
@@ -44,10 +45,6 @@ public abstract class AbstractRouter implements Router {
         this.url = url;
     }
 
-    public void setConfiguration(DynamicConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
     @Override
     public boolean isRuntime() {
         return true;
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouter.java
index 852da6b..59a63c7 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouter.java
@@ -17,7 +17,6 @@
 package org.apache.dubbo.rpc.cluster.router.condition.config;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 import org.apache.dubbo.common.constants.CommonConstants;
 
 /**
@@ -30,8 +29,8 @@ public class AppRouter extends ListenableRouter {
      */
     private static final int APP_ROUTER_DEFAULT_PRIORITY = 150;
 
-    public AppRouter(DynamicConfiguration configuration, URL url) {
-        super(configuration, url, url.getParameter(CommonConstants.APPLICATION_KEY));
+    public AppRouter(URL url) {
+        super(url, url.getParameter(CommonConstants.APPLICATION_KEY));
         this.priority = APP_ROUTER_DEFAULT_PRIORITY;
     }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouterFactory.java
index 067a523..c0464d8 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouterFactory.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppRouterFactory.java
@@ -17,7 +17,6 @@
 package org.apache.dubbo.rpc.cluster.router.condition.config;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.rpc.cluster.Router;
 import org.apache.dubbo.rpc.cluster.RouterFactory;
@@ -45,6 +44,6 @@ public class AppRouterFactory implements RouterFactory {
     }
 
     private Router createRouter(URL url) {
-        return new AppRouter(DynamicConfiguration.getDynamicConfiguration(), url);
+        return new AppRouter(url);
     }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
index 6d3276a..41044ec 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
@@ -49,8 +49,8 @@ public abstract class ListenableRouter extends AbstractRouter implements Configu
     private ConditionRouterRule routerRule;
     private List<ConditionRouter> conditionRouters = Collections.emptyList();
 
-    public ListenableRouter(DynamicConfiguration configuration, URL url, String ruleKey) {
-        super(configuration, url);
+    public ListenableRouter(URL url, String ruleKey) {
+        super(url);
         this.force = false;
         this.init(ruleKey);
     }
@@ -118,8 +118,8 @@ public abstract class ListenableRouter extends AbstractRouter implements Configu
             return;
         }
         String routerKey = ruleKey + RULE_SUFFIX;
-        configuration.addListener(routerKey, this);
-        String rule = configuration.getConfig(routerKey, DynamicConfiguration.DEFAULT_GROUP);
+        ruleRepository.addListener(routerKey, this);
+        String rule = ruleRepository.getRule(routerKey, DynamicConfiguration.DEFAULT_GROUP);
         if (StringUtils.isNotEmpty(rule)) {
             this.process(new ConfigChangeEvent(routerKey, rule));
         }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
index 2a50052..93ebf8b 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
@@ -29,8 +29,8 @@ public class ServiceRouter extends ListenableRouter {
      */
     private static final int SERVICE_ROUTER_DEFAULT_PRIORITY = 140;
 
-    public ServiceRouter(DynamicConfiguration configuration, URL url) {
-        super(configuration, url, DynamicConfiguration.getRuleKey(url));
+    public ServiceRouter(URL url) {
+        super(url, DynamicConfiguration.getRuleKey(url));
         this.priority = SERVICE_ROUTER_DEFAULT_PRIORITY;
     }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouterFactory.java
index 12911ac..af971d7 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouterFactory.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouterFactory.java
@@ -17,7 +17,6 @@
 package org.apache.dubbo.rpc.cluster.router.condition.config;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.rpc.cluster.CacheableRouterFactory;
 import org.apache.dubbo.rpc.cluster.Router;
@@ -32,7 +31,7 @@ public class ServiceRouterFactory extends CacheableRouterFactory {
 
     @Override
     protected Router createRouter(URL url) {
-        return new ServiceRouter(DynamicConfiguration.getDynamicConfiguration(), url);
+        return new ServiceRouter(url);
     }
 
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
index 00ce099..05b1a11 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
@@ -55,8 +55,8 @@ public class TagRouter extends AbstractRouter implements ConfigurationListener {
     private TagRouterRule tagRouterRule;
     private String application;
 
-    public TagRouter(DynamicConfiguration configuration, URL url) {
-        super(configuration, url);
+    public TagRouter(URL url) {
+        super(url);
         this.priority = TAG_ROUTER_DEFAULT_PRIORITY;
     }
 
@@ -244,12 +244,12 @@ public class TagRouter extends AbstractRouter implements ConfigurationListener {
         synchronized (this) {
             if (!providerApplication.equals(application)) {
                 if (!StringUtils.isEmpty(application)) {
-                    configuration.removeListener(application + RULE_SUFFIX, this);
+                    ruleRepository.removeListener(application + RULE_SUFFIX, this);
                 }
                 String key = providerApplication + RULE_SUFFIX;
-                configuration.addListener(key, this);
+                ruleRepository.addListener(key, this);
                 application = providerApplication;
-                String rawRule = configuration.getConfig(key, DynamicConfiguration.DEFAULT_GROUP);
+                String rawRule = ruleRepository.getRule(key, DynamicConfiguration.DEFAULT_GROUP);
                 if (StringUtils.isNotEmpty(rawRule)) {
                     this.process(new ConfigChangeEvent(key, rawRule));
                 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
index 0df085d..3c9a60e 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
@@ -17,7 +17,6 @@
 package org.apache.dubbo.rpc.cluster.router.tag;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.rpc.cluster.CacheableRouterFactory;
 import org.apache.dubbo.rpc.cluster.Router;
@@ -32,6 +31,6 @@ public class TagRouterFactory extends CacheableRouterFactory {
 
     @Override
     protected Router createRouter(URL url) {
-        return new TagRouter(DynamicConfiguration.getDynamicConfiguration(), url);
+        return new TagRouter(url);
     }
 }
diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository
new file mode 100644
index 0000000..067a72e
--- /dev/null
+++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository
@@ -0,0 +1 @@
+default=org.apache.dubbo.rpc.cluster.governance.DefaultGovernanceRuleRepositoryImpl
\ No newline at end of file
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java
index 94ff25f..f687c85 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java
@@ -16,6 +16,8 @@
  */
 package org.apache.dubbo.common.config;
 
+import java.util.NoSuchElementException;
+
 /**
  * Configuration interface, to fetch the value for the specified key.
  */
@@ -44,6 +46,49 @@ public interface Configuration {
         return convert(String.class, key, defaultValue);
     }
 
+    default int getInt(String key) {
+        Integer i = this.getInteger(key, (Integer) null);
+        if (i != null) {
+            return i;
+        } else {
+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    default int getInt(String key, int defaultValue) {
+        Integer i = this.getInteger(key, (Integer) null);
+        return i == null ? defaultValue : i;
+    }
+
+    default Integer getInteger(String key, Integer defaultValue) {
+        try {
+            return convert(Integer.class, key, defaultValue);
+        } catch (NumberFormatException e) {
+            throw new IllegalStateException('\'' + key + "' doesn't map to a Integer object", e);
+        }
+    }
+
+    default boolean getBoolean(String key) {
+        Boolean b = this.getBoolean(key, null);
+        if (b != null) {
+            return b;
+        } else {
+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    default boolean getBoolean(String key, boolean defaultValue) {
+        return this.getBoolean(key, toBooleanObject(defaultValue));
+    }
+
+    default Boolean getBoolean(String key, Boolean defaultValue) {
+        try {
+            return convert(Boolean.class, key, defaultValue);
+        } catch (Exception e) {
+            throw new IllegalStateException("Try to get " + '\'' + key + "' failed, maybe because this key doesn't map to a Boolean object", e);
+        }
+    }
+
     /**
      * Gets a property from the configuration. This is the most basic get
      * method for retrieving values of properties. In a typical implementation
@@ -127,4 +172,8 @@ public interface Configuration {
 
         return cls.cast(obj);
     }
+
+    static Boolean toBooleanObject(boolean bool) {
+        return bool ? Boolean.TRUE : Boolean.FALSE;
+    }
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java
index 604be99..3b7d3b3 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java
@@ -75,11 +75,6 @@ public abstract class AbstractDynamicConfiguration implements DynamicConfigurati
     }
 
     @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        return getConfig(key, group, timeout);
-    }
-
-    @Override
     public Object getInternalProperty(String key) {
         return null;
     }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java
index 852ec62..777f50b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java
@@ -35,7 +35,6 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad
  * <br/>
  * From the use scenario internally inside framework, there're mainly three kinds of methods:
  * <ol>
- * <li>{@link #getRule(String, String, long)}, get governance rules.</li>
  * <li>{@link #getProperties(String, String, long)}, get configuration file from Config Center at start up.</li>
  * <li>{@link #addListener(String, String, ConfigurationListener)}/ {@link #removeListener(String, String, ConfigurationListener)}
  * , add or remove listeners for governance rules or config items that need to watch.</li>
@@ -128,31 +127,6 @@ public interface DynamicConfiguration extends Configuration, AutoCloseable {
     }
 
     /**
-     * Get the governance rule mapped to the given key and the given group
-     *
-     * @param key   the key to represent a configuration
-     * @param group the group where the key belongs to
-     * @return target configuration mapped to the given key and the given group
-     * @since 2.7.3
-     */
-    default String getRule(String key, String group) {
-        return getRule(key, group, -1L);
-    }
-
-    /**
-     * Get the governance rule mapped to the given key and the given group. If the
-     * rule fails to return after timeout exceeds, IllegalStateException will be thrown.
-     *
-     * @param key     the key to represent a configuration
-     * @param group   the group where the key belongs to
-     * @param timeout timeout value for fetching the target config
-     * @return target configuration mapped to the given key and the given group, IllegalStateException will be thrown
-     * if timeout exceeds.
-     * @since 2.7.3
-     */
-    String getRule(String key, String group, long timeout) throws IllegalStateException;
-
-    /**
      * Publish Config mapped to the given key under the {@link #DEFAULT_GROUP default group}
      *
      * @param key     the key to represent a configuration
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfiguration.java
index 5b37c34..715fd87 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfiguration.java
@@ -348,11 +348,6 @@ public class FileSystemDynamicConfiguration implements DynamicConfiguration {
         });
     }
 
-    @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        return getConfig(key, group, timeout);
-    }
-
     protected String getConfig(File configFile, long timeout) {
         return canRead(configFile) ? execute(() -> readFileToString(configFile, getEncoding()), timeout) : null;
     }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
index 7940101..e61af12 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
@@ -56,12 +56,6 @@ public class NopDynamicConfiguration implements DynamicConfiguration {
         return null;
     }
 
-    @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        // no-op
-        return null;
-    }
-
     /**
      * @since 2.7.4
      */
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
index e86d656..16484e7 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
@@ -55,11 +55,6 @@ public class CompositeDynamicConfiguration implements DynamicConfiguration {
     }
 
     @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        return (String) iterateConfigOperation(configuration -> configuration.getRule(key, group, timeout));
-    }
-
-    @Override
     public String getProperties(String key, String group, long timeout) throws IllegalStateException {
         return (String) iterateConfigOperation(configuration -> configuration.getProperties(key, group, timeout));
     }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
index 5502bdf..17ead90 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
@@ -83,7 +83,7 @@ public class FileSystemDynamicConfigurationTest {
         assertTrue(configuration.publishConfig(KEY, CONTENT));
         assertTrue(configuration.publishConfig(KEY, CONTENT));
         assertTrue(configuration.publishConfig(KEY, CONTENT));
-        assertEquals(CONTENT, configuration.getRule(KEY, DEFAULT_GROUP));
+        assertEquals(CONTENT, configuration.getConfig(KEY, DEFAULT_GROUP));
         assertTrue(configuration.getConfigs(null).size() > 0);
     }
 
diff --git a/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
index cd20dc2..603dd73 100644
--- a/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
@@ -147,7 +147,7 @@ public class ApolloDynamicConfiguration implements DynamicConfiguration {
     }
 
     @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
+    public String getProperties(String key, String group, long timeout) throws IllegalStateException {
         if (StringUtils.isEmpty(group)) {
             return dubboConfigFile.getContent();
         }
diff --git a/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
index 9a698a3..e6d5c74 100644
--- a/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
@@ -98,14 +98,6 @@ public class ConsulDynamicConfiguration implements DynamicConfiguration {
     }
 
     @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        if (StringUtils.isEmpty(group)) {
-            group = DEFAULT_GROUP;
-        }
-        return getConfig(key, group, timeout);
-    }
-
-    @Override
     public Object getInternalProperty(String key) {
         logger.info("get config from: " + key);
         Response<GetValue> response = getValue(key);
@@ -127,8 +119,13 @@ public class ConsulDynamicConfiguration implements DynamicConfiguration {
         return null;
     }
 
+    private String buildPath(String group) {
+        String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
+        return rootPath + PATH_SEPARATOR + actualGroup;
+    }
+
     private String convertKey(String group, String key) {
-        return rootPath + PATH_SEPARATOR + group + PATH_SEPARATOR + key;
+        return buildPath(group) + PATH_SEPARATOR + key;
     }
 
     private int buildWatchTimeout(URL url) {
diff --git a/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
index c5b48b7..356161a 100644
--- a/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.config.configcenter.ConfigChangeEvent;
 import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
 import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.etcd.StateListener;
 import org.apache.dubbo.remoting.etcd.jetcd.JEtcdClient;
 
@@ -98,11 +99,6 @@ public class EtcdDynamicConfiguration implements DynamicConfiguration {
         return (String) getInternalProperty(convertKey(group, key));
     }
 
-    @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        return getConfig(key, group, timeout);
-    }
-
 //    @Override
 //    public String getConfigs(String key, String group, long timeout) throws IllegalStateException {
 //        if (StringUtils.isEmpty(group)) {
@@ -116,9 +112,13 @@ public class EtcdDynamicConfiguration implements DynamicConfiguration {
         return etcdClient.getKVValue(key);
     }
 
+    private String buildPath(String group) {
+        String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
+        return rootPath + PATH_SEPARATOR + actualGroup;
+    }
 
     private String convertKey(String group, String key) {
-        return rootPath + PATH_SEPARATOR + group + PATH_SEPARATOR + key;
+        return buildPath(group) + PATH_SEPARATOR + key;
     }
 
     private void recover() {
diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
index bc3f900..5b40527 100644
--- a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -199,11 +199,6 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
     }
 
     @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        return getConfig(key, group, timeout);
-    }
-
-    @Override
     public Object getInternalProperty(String key) {
         try {
             return configService.getConfig(key, DEFAULT_GROUP, DEFAULT_TIMEOUT);
diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
index a346ecc..b36c023 100644
--- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
@@ -111,16 +111,6 @@ public class ZookeeperDynamicConfiguration implements DynamicConfiguration {
     }
 
     @Override
-    public String getRule(String key, String group, long timeout) throws IllegalStateException {
-        return getConfig(key, group, timeout);
-    }
-
-    @Override
-    public String getProperties(String key, String group, long timeout) throws IllegalStateException {
-        return getConfig(key, group, timeout);
-    }
-
-    @Override
     public boolean publishConfig(String key, String group, String content) {
         String path = getPathKey(key, group);
         zkClient.create(path, content, true);
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
index fd824ba..6c5b72f 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
@@ -24,8 +24,10 @@ import org.apache.dubbo.qos.server.Server;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
 
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
@@ -78,6 +80,11 @@ public class QosProtocolWrapper implements Protocol {
         stopServer();
     }
 
+    @Override
+    public List<ProtocolServer> getServers() {
+        return protocol.getServers();
+    }
+
     private void startQosServer(URL url) {
         try {
             if (!hasStarted.compareAndSet(false, true)) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
index 308ca52..cf774ab 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
@@ -20,11 +20,13 @@ import org.apache.dubbo.common.config.configcenter.ConfigChangeEvent;
 import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
 import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.cluster.Configurator;
 import org.apache.dubbo.rpc.cluster.configurator.parser.ConfigParser;
+import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
 
 import java.util.Collections;
 import java.util.List;
@@ -39,9 +41,9 @@ public abstract class AbstractConfiguratorListener implements ConfigurationListe
 
 
     protected final void initWith(String key) {
-        DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
-        dynamicConfiguration.addListener(key, this);
-        String rawConfig = dynamicConfiguration.getRule(key, DynamicConfiguration.DEFAULT_GROUP);
+        GovernanceRuleRepository ruleRepository = ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
+        ruleRepository.addListener(key, this);
+        String rawConfig = ruleRepository.getRule(key, DynamicConfiguration.DEFAULT_GROUP);
         if (!StringUtils.isEmpty(rawConfig)) {
             genConfiguratorsFromRawRule(rawConfig);
         }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
index 0166d72..9592d76 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
@@ -42,6 +42,7 @@ import org.apache.dubbo.rpc.cluster.RouterChain;
 import org.apache.dubbo.rpc.cluster.RouterFactory;
 import org.apache.dubbo.rpc.cluster.directory.AbstractDirectory;
 import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
+import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
 import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.protocol.InvokerWrapper;
@@ -192,7 +193,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
             if (getConsumerUrl() != null && registry != null && registry.isAvailable()) {
                 registry.unsubscribe(getConsumerUrl(), this);
             }
-            DynamicConfiguration.getDynamicConfiguration()
+            ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
                     .removeListener(ApplicationModel.getApplication(), CONSUMER_CONFIGURATION_LISTENER);
         } catch (Throwable t) {
             logger.warn("unexpected error when unsubscribe service " + serviceKey + "from registry" + registry.getUrl(), t);
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
index bae63ec..089383c 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
@@ -39,6 +39,7 @@ import org.apache.dubbo.rpc.ProxyFactory;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.cluster.Cluster;
 import org.apache.dubbo.rpc.cluster.Configurator;
+import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.invoker.ProviderInvokerWrapper;
 import org.apache.dubbo.rpc.protocol.InvokerWrapper;
@@ -443,7 +444,7 @@ public class RegistryProtocol implements Protocol {
         }
         bounds.clear();
 
-        DynamicConfiguration.getDynamicConfiguration()
+        ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
                 .removeListener(ApplicationModel.getApplication() + CONFIGURATORS_SUFFIX, providerConfigurationListener);
     }
 
@@ -680,7 +681,7 @@ public class RegistryProtocol implements Protocol {
             try {
                 NotifyListener listener = RegistryProtocol.INSTANCE.overrideListeners.remove(subscribeUrl);
                 registry.unsubscribe(subscribeUrl, listener);
-                DynamicConfiguration.getDynamicConfiguration()
+                ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
                         .removeListener(subscribeUrl.getServiceKey() + CONFIGURATORS_SUFFIX,
                                 serviceConfigurationListeners.get(subscribeUrl.getServiceKey()));
             } catch (Throwable t) {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java
index 3da2b95..02b8d49 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java
@@ -29,13 +29,12 @@ public interface ProtocolServer {
         return null;
     }
 
-    default void setRemotingServers() {
-
+    default void setRemotingServers(RemotingServer server) {
     }
 
     String getAddress();
 
-    void setAddress();
+    void setAddress(String address);
 
     default URL getUrl() {
         return null;
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
index 4b5c016..7ee976e 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
@@ -172,7 +172,7 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol {
         }
 
         @Override
-        public void setAddress() {
+        public void setAddress(String address) {
             this.address = address;
         }
 
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java
index d0933bc..29abfa0 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java
@@ -41,7 +41,7 @@ public class DubboProtocolServer implements ProtocolServer {
     }
 
     @Override
-    public void setAddress() {
+    public void setAddress(String address) {
         this.address = address;
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
index f16967d..3621848 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
@@ -26,6 +26,8 @@ import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
 
 public abstract class BaseRestProtocolServer implements RestProtocolServer {
 
+    private String address;
+
     @Override
     public void start(URL url) {
         getDeployment().getMediaTypeMappings().put("json", "application/json");
@@ -54,6 +56,16 @@ public abstract class BaseRestProtocolServer implements RestProtocolServer {
         getDeployment().getRegistry().removeRegistrations(resourceDef);
     }
 
+    @Override
+    public String getAddress() {
+        return address;
+    }
+
+    @Override
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
     protected void loadProviders(String value) {
         for (String clazz : COMMA_SPLIT_PATTERN.split(value)) {
             if (!StringUtils.isEmpty(clazz)) {
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
similarity index 97%
rename from dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java
rename to dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
index e07d0a7..1ab039a 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
@@ -36,7 +36,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Enumeration;
 
-public class DubboHttpServer extends BaseRestProtocolServer {
+public class DubboHttpProtocolServer extends BaseRestProtocolServer {
 
     private final HttpServletDispatcher dispatcher = new HttpServletDispatcher();
     private final ResteasyDeployment deployment = new ResteasyDeployment();
@@ -44,7 +44,7 @@ public class DubboHttpServer extends BaseRestProtocolServer {
     private HttpServer httpServer;
 //    private boolean isExternalServer;
 
-    public DubboHttpServer(HttpBinder httpBinder) {
+    public DubboHttpProtocolServer(HttpBinder httpBinder) {
         this.httpBinder = httpBinder;
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
index fe30443..62b1af6 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
@@ -97,6 +97,7 @@ public class RestProtocol extends AbstractProxyProtocol {
         Class implClass = ApplicationModel.getProviderModel(url.getPathKey()).getServiceInstance().getClass();
         RestProtocolServer server = (RestProtocolServer) serverMap.computeIfAbsent(addr, restServer -> {
             RestProtocolServer s = serverFactory.createServer(url.getParameter(SERVER_KEY, DEFAULT_SERVER));
+            s.setAddress(url.getAddress());
             s.start(url);
             return s;
         });
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
index 6de7ba1..6fcf7f6 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
@@ -34,7 +34,7 @@ public class RestServerFactory {
     public RestProtocolServer createServer(String name) {
         // TODO move names to Constants
         if ("servlet".equalsIgnoreCase(name) || "jetty".equalsIgnoreCase(name) || "tomcat".equalsIgnoreCase(name)) {
-            return new DubboHttpServer(httpBinder);
+            return new DubboHttpProtocolServer(httpBinder);
         } else if ("netty".equalsIgnoreCase(name)) {
             return new NettyRestProtocolServer();
         } else {
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
index b5c492e..76bca80 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
@@ -246,7 +246,7 @@ public class ThriftProtocol extends AbstractProtocol {
         }
 
         @Override
-        public void setAddress() {
+        public void setAddress(String address) {
             this.address = address;
         }
 


[dubbo] 02/04: Merge branch 'cloud-native' of https://github.com/apache/dubbo into cloud-native

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b7b34b6c475912c4c805b389954fd897bdd9f769
Merge: 550b404 03173f8
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Aug 8 16:22:48 2019 +0800

    Merge branch 'cloud-native' of https://github.com/apache/dubbo into cloud-native

 .travis.yml                                        |   2 +-
 dubbo-bom/pom.xml                                  |   1 +
 dubbo-bootstrap/pom.xml                            |  40 +--
 .../org/apache/dubbo/bootstrap/DubboBootstrap.java |  25 +-
 .../bootstrap/DubboServiceConsumerBootstrap.java   |   3 +-
 ...ap.java => DubboServiceProvider2Bootstrap.java} |  34 +--
 dubbo-cluster/pom.xml                              |   1 +
 .../router/condition/config/ListenableRouter.java  |   2 +-
 .../dubbo/rpc/cluster/router/tag/TagRouter.java    |   2 +-
 .../support/wrapper/MockClusterInvoker.java        |   2 +-
 .../dubbo/rpc/cluster/router/TagRouterTest.java    |   5 +-
 .../support/AbstractClusterInvokerTest.java        |   2 +-
 dubbo-common/pom.xml                               |   1 +
 .../apache/dubbo/common/config/Configuration.java  |   2 -
 .../configcenter/AbstractDynamicConfiguration.java | 182 ++++++++++++
 .../config/configcenter/DynamicConfiguration.java  |  86 ++++--
 .../file/FileSystemDynamicConfiguration.java       |  23 +-
 .../configcenter/nop/NopDynamicConfiguration.java  |   6 +-
 .../wrapper/CompositeDynamicConfiguration.java     |   5 +
 .../dubbo/common/constants/CommonConstants.java    |   2 +-
 .../extension/AdaptiveClassCodeGenerator.java      |  10 +-
 .../apache/dubbo/common/bytecode/MixinTest.java    |   1 -
 .../common/config/InmemoryConfigurationTest.java   |   6 +-
 .../threadlocal/InternalThreadLocalTest.java       |   1 -
 .../apache/dubbo/common/utils/PojoUtilsTest.java   |   5 +-
 dubbo-compatible/pom.xml                           |   1 +
 .../dubbo/rpc/protocol/dubbo/FutureAdapter.java    |   6 +-
 .../org/apache/dubbo/config/MethodConfigTest.java  |   1 -
 .../org/apache/dubbo/filter/LegacyInvoker.java     |   2 +-
 .../java/org/apache/dubbo/rpc/RpcContextTest.java  |   6 +-
 dubbo-config/dubbo-config-api/pom.xml              |   1 +
 .../org/apache/dubbo/config/ApplicationConfig.java |   1 -
 .../org/apache/dubbo/config/ReferenceConfig.java   |  14 +-
 .../org/apache/dubbo/config/RegistryConfig.java    |  10 +-
 .../org/apache/dubbo/config/ServiceConfig.java     |   5 +-
 .../apache/dubbo/config/ReferenceConfigTest.java   |   8 +-
 .../ConfigurableMetadataServiceExporterTest.java   |   5 +-
 dubbo-config/dubbo-config-spring/pom.xml           |   1 +
 .../factory/annotation/ReferenceBeanBuilder.java   |   9 +
 .../ServiceAnnotationBeanPostProcessor.java        |  14 +
 .../dubbo/config/spring/util/AnnotationUtils.java  |  20 +-
 .../ReferenceAnnotationBeanPostProcessorTest.java  |  89 +++---
 .../ServiceAnnotationBeanPostProcessorTest.java    |  13 +
 .../context/annotation/EnableDubboConfigTest.java  |  11 +
 .../annotation/provider/DemoServiceImpl.java       |   4 +-
 .../DubboComponentScanRegistrarTest.java           | 118 --------
 .../DubboConfigBindingRegistrarTest.java           |  88 ------
 .../DubboConfigBindingsRegistrarTest.java          |  63 -----
 .../annotation/DubboConfigConfigurationTest.java   |  99 -------
 .../context/annotation/EnableDubboConfigTest.java  | 120 --------
 .../context/annotation/EnableDubboTest.java        | 162 -----------
 .../annotation/consumer/ConsumerConfiguration.java | 126 ---------
 .../consumer/test/TestConsumerConfiguration.java   |  96 -------
 .../annotation/provider/DemoServiceImpl.java       |  55 ----
 .../annotation/provider/ProviderConfiguration.java | 109 --------
 .../properties/DefaultDubboConfigBinderTest.java   |  94 -------
 dubbo-config/pom.xml                               |   1 +
 .../support/nop/NopDynamicConfigurationTest.java   |  70 -----
 .../dubbo-configcenter-apollo/pom.xml              |   1 +
 .../support/apollo/ApolloDynamicConfiguration.java |  10 +-
 .../dubbo-configcenter-consul/pom.xml              |   3 +-
 .../consul/ConsulDynamicConfiguration.java         |   6 +-
 dubbo-configcenter/dubbo-configcenter-etcd/pom.xml |   3 +-
 .../support/etcd/EtcdDynamicConfiguration.java     |  20 +-
 .../dubbo-configcenter-nacos/pom.xml               |   3 +-
 .../support/nacos/NacosDynamicConfiguration.java   |   8 +-
 .../nacos/NacosDynamicConfigurationTest.java       |   6 +-
 .../dubbo-configcenter-zookeeper/pom.xml           |   1 +
 .../zookeeper/ZookeeperDynamicConfiguration.java   |  84 +++---
 .../ZookeeperDynamicConfigurationTest.java         |   2 +-
 dubbo-configcenter/pom.xml                         |   1 +
 dubbo-container/dubbo-container-api/pom.xml        |   1 +
 dubbo-container/dubbo-container-log4j/pom.xml      |   1 +
 dubbo-container/dubbo-container-logback/pom.xml    |   1 +
 dubbo-container/dubbo-container-spring/pom.xml     |   1 +
 dubbo-container/pom.xml                            |   1 +
 .../dubbo-demo-annotation-consumer/pom.xml         |   3 +-
 .../resources/spring/dubbo-consumer.properties     |   2 +-
 .../dubbo-demo-annotation-provider/pom.xml         |   3 +-
 .../apache/dubbo/demo/provider/Application.java    |   6 +-
 .../dubbo-demo-api/dubbo-demo-api-consumer/pom.xml |   3 +-
 .../apache/dubbo/demo/consumer/Application.java    |   6 +-
 .../dubbo-demo-api/dubbo-demo-api-provider/pom.xml |   3 +-
 .../apache/dubbo/demo/provider/Application.java    |   6 +-
 dubbo-demo/dubbo-demo-api/pom.xml                  |   3 +-
 dubbo-demo/dubbo-demo-interface/pom.xml            |   1 +
 .../dubbo-demo-xml/dubbo-demo-xml-consumer/pom.xml |   1 +
 .../apache/dubbo/demo/consumer/Application.java    |   4 -
 .../src/main/resources/spring/dubbo-consumer.xml   |   4 +-
 .../dubbo-demo-xml/dubbo-demo-xml-provider/pom.xml |   4 +-
 .../apache/dubbo/demo/provider/Application.java    |   4 -
 .../src/main/resources/spring/dubbo-provider.xml   |   6 +-
 dubbo-demo/dubbo-demo-xml/pom.xml                  |   3 +-
 dubbo-demo/pom.xml                                 |   1 +
 dubbo-dependencies/pom.xml                         |   3 +-
 dubbo-distribution/pom.xml                         |   1 +
 dubbo-filter/dubbo-filter-cache/pom.xml            |   1 +
 dubbo-filter/dubbo-filter-validation/pom.xml       |   1 +
 dubbo-filter/pom.xml                               |   1 +
 dubbo-metadata/dubbo-metadata-api/pom.xml          |   1 +
 .../DynamicConfigurationServiceNameMapping.java    |  13 +-
 .../org/apache/dubbo/metadata/MetadataService.java |  99 +++++--
 .../org/apache/dubbo/metadata/MetadataUtil.java    |  33 +++
 .../dubbo/metadata/WritableMetadataService.java    |   2 +-
 .../definition/model/MethodDefinition.java         |  18 +-
 .../store/InMemoryWritableMetadataService.java     | 101 +++----
 .../store/RemoteWritableMetadataService.java       |  20 +-
 ...g.apache.dubbo.metadata.WritableMetadataService |   2 +-
 ...DynamicConfigurationServiceNameMappingTest.java |  38 +--
 .../InMemoryWritableMetadataServiceTest.java       |  32 ++-
 .../report/identifier/MetadataIdentifierTest.java  |   2 +-
 .../report/support/AbstractMetadataReportTest.java |  14 +-
 .../store/RemoteWritableMeatadataServiceTest.java  |   4 +-
 ...che.dubbo.metadata.report.MetadataReportFactory |   1 +
 .../dubbo-metadata-definition-protobuf/pom.xml     |   4 +-
 .../definition/protobuf/ProtobufTypeBuilder.java   | 308 +++++++++++++++++++++
 ...e.dubbo.metadata.definition.builder.TypeBuilder |   0
 .../protobuf/ProtobufTypeBuilderTest.java          |  71 +++++
 .../definition/protobuf/model/GooglePB.java        |   0
 .../protobuf/model/ServiceInterface.java           |   0
 .../dubbo-metadata-report-consul/pom.xml           |   3 +-
 dubbo-metadata/dubbo-metadata-report-etcd/pom.xml  |   3 +-
 dubbo-metadata/dubbo-metadata-report-nacos/pom.xml |   3 +-
 dubbo-metadata/dubbo-metadata-report-redis/pom.xml |   3 +-
 .../dubbo-metadata-report-zookeeper/pom.xml        |   4 +-
 dubbo-metadata/pom.xml                             |   2 +-
 dubbo-monitor/dubbo-monitor-api/pom.xml            |   1 +
 dubbo-monitor/dubbo-monitor-default/pom.xml        |   1 +
 .../dubbo/monitor/dubbo/MetricsFilterTest.java     |   2 -
 dubbo-monitor/pom.xml                              |   1 +
 dubbo-plugin/dubbo-qos/pom.xml                     |   1 +
 .../dubbo/qos/command/util/CommandHelperTest.java  |   3 +-
 dubbo-plugin/pom.xml                               |   3 +-
 dubbo-registry/dubbo-registry-api/pom.xml          |   1 +
 .../dubbo/registry/client/ServiceInstance.java     |  43 ---
 .../CompositeMetadataServiceURLBuilder.java        |  81 ++++++
 ...ExportedServicesRevisionMetadataCustomizer.java |   4 +-
 .../client/metadata/MetadataServiceProxy.java      |   9 +-
 .../client/metadata/MetadataServiceURLBuilder.java |  60 ++--
 ...MetadataServiceURLParamsMetadataCustomizer.java |   4 +-
 .../metadata/ServiceInstanceMetadataUtils.java     |  14 +-
 .../SpringCloudMetadataServiceURLBuilder.java      |  49 ++++
 ...java => StandardMetadataServiceURLBuilder.java} |  13 +-
 .../proxy/DefaultMetadataServiceProxyFactory.java  |  11 +-
 .../proxy/MetadataServiceProxyFactory.java         |   2 +-
 .../registry/support/ServiceOrientedRegistry.java  |  32 ++-
 ...try.client.metadata.MetadataServiceProxyFactory |   1 -
 ...ient.metadata.proxy.MetadataServiceProxyFactory |   2 +-
 ...istry.client.metadata.MetadataServiceURLBuilder |   2 +
 .../client/DefaultServiceInstanceTest.java         |  36 ++-
 .../CustomizableServiceInstanceListenerTest.java   |  29 +-
 .../event/listener/LoggingEventListenerTest.java   |  85 ++++++
 .../ServiceInstancesChangedListenerTest.java       |  54 ++++
 .../metadata/MetadataServiceURLBuilderTest.java    |  53 ++++
 .../metadata/ServiceInstanceMetadataUtilsTest.java |  17 +-
 .../SpringCloudMetadataServiceURLBuilderTest.java  |  51 ++++
 .../support/ServiceOrientedRegistryTest.java       |  32 ++-
 dubbo-registry/dubbo-registry-consul/pom.xml       |   1 +
 .../registry/consul/AbstractConsulRegistry.java    |  27 ++
 .../dubbo/registry/consul/ConsulRegistry.java      |  23 +-
 .../registry/consul/ConsulServiceDiscovery.java    | 196 +++++++++++++
 .../consul/ConsulServiceDiscoveryFactory.java      |  19 +-
 dubbo-registry/dubbo-registry-default/pom.xml      |   1 +
 .../dubbo/registry/dubbo/RegistryProtocolTest.java |   2 +-
 dubbo-registry/dubbo-registry-etcd3/pom.xml        |   1 +
 .../dubbo/registry/etcd/EtcdServiceDiscovery.java  |  13 +-
 .../dubbo/registry/etcd/EtcdRegistryTest.java      |   2 +-
 dubbo-registry/dubbo-registry-multicast/pom.xml    |   1 +
 .../registry/multicast/MulticastRegistry.java      |   6 +-
 dubbo-registry/dubbo-registry-multiple/pom.xml     |   1 +
 .../dubbo/registry/nacos/NacosRegistryFactory.java |   3 -
 .../nacos/util/NacosNamingServiceUtils.java        |   3 +-
 dubbo-registry/dubbo-registry-redis/pom.xml        |   1 +
 dubbo-registry/dubbo-registry-zookeeper/pom.xml    |   1 +
 .../registry/zookeeper/ZookeeperRegistry.java      |   2 -
 .../zookeeper/ZookeeperServiceDiscovery.java       |  37 +++
 .../registry/zookeeper/ZookeeperRegistryTest.java  |   3 +-
 .../zookeeper/ZookeeperServiceDiscoveryTest.java   |   2 +
 dubbo-registry/pom.xml                             |   1 +
 dubbo-remoting/dubbo-remoting-api/pom.xml          |   1 +
 .../dubbo/remoting/PerformanceClientFixedTest.java |   2 +-
 .../remoting/transport/AbstractCodecTest.java      |   5 +-
 dubbo-remoting/dubbo-remoting-etcd3/pom.xml        |   1 +
 dubbo-remoting/dubbo-remoting-grizzly/pom.xml      |   1 +
 dubbo-remoting/dubbo-remoting-http/pom.xml         |   1 +
 dubbo-remoting/dubbo-remoting-mina/pom.xml         |   1 +
 dubbo-remoting/dubbo-remoting-netty/pom.xml        |   1 +
 dubbo-remoting/dubbo-remoting-netty4/pom.xml       |   1 +
 dubbo-remoting/dubbo-remoting-p2p/pom.xml          |   1 +
 dubbo-remoting/dubbo-remoting-zookeeper/pom.xml    |   1 +
 .../zookeeper/curator/CuratorZookeeperClient.java  |   5 +
 dubbo-remoting/pom.xml                             |   1 +
 dubbo-rpc/dubbo-rpc-api/pom.xml                    |   1 +
 .../dubbo/rpc/filter/AccessLogFilterTest.java      |   7 +-
 .../apache/dubbo/rpc/support/BlockMyInvoker.java   |   2 +-
 .../apache/dubbo/rpc/support/MockInvokerTest.java  |  11 +-
 .../org/apache/dubbo/rpc/support/MyInvoker.java    |   2 +-
 .../org/apache/dubbo/rpc/support/RpcUtilsTest.java |   4 +-
 dubbo-rpc/dubbo-rpc-dubbo/pom.xml                  |   1 +
 .../dubbo/rpc/protocol/dubbo/DubboProtocol.java    |   2 +-
 .../dubbo/ReferenceCountExchangeClient.java        |   3 +
 dubbo-rpc/dubbo-rpc-hessian/pom.xml                |   1 +
 dubbo-rpc/dubbo-rpc-http/pom.xml                   |   1 +
 dubbo-rpc/dubbo-rpc-injvm/pom.xml                  |   1 +
 dubbo-rpc/dubbo-rpc-jsonrpc/pom.xml                |   1 +
 dubbo-rpc/dubbo-rpc-memcached/pom.xml              |   1 +
 dubbo-rpc/dubbo-rpc-native-thrift/pom.xml          |   1 +
 dubbo-rpc/dubbo-rpc-redis/pom.xml                  |   1 +
 dubbo-rpc/dubbo-rpc-rest/pom.xml                   |   1 +
 .../DubboSwaggerApiListingResourceTest.java        |   4 +-
 dubbo-rpc/dubbo-rpc-rmi/pom.xml                    |   1 +
 .../dubbo/rpc/protocol/rmi/RmiProtocolTest.java    |   4 +-
 dubbo-rpc/dubbo-rpc-thrift/pom.xml                 |   1 +
 dubbo-rpc/dubbo-rpc-webservice/pom.xml             |   1 +
 dubbo-rpc/dubbo-rpc-xml/pom.xml                    |   1 +
 .../xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java    |   2 +-
 dubbo-rpc/pom.xml                                  |   1 +
 .../dubbo-serialization-api/pom.xml                |   1 +
 .../dubbo-serialization-avro/pom.xml               |   1 +
 .../common/serialize/avro/AvroObjectInput.java     |   3 +-
 .../common/serialize/avro/AvroObjectOutput.java    |   3 +-
 .../dubbo-serialization-fastjson/pom.xml           |   1 +
 .../dubbo-serialization-fst/pom.xml                |   1 +
 .../dubbo-serialization-gson/pom.xml               |   1 +
 .../dubbo-serialization-hessian2/pom.xml           |   1 +
 .../dubbo-serialization-jdk/pom.xml                |   1 +
 .../dubbo-serialization-kryo/pom.xml               |   1 +
 .../dubbo-serialization-native-hession/pom.xml     |   3 +-
 .../dubbo-serialization-protobuf-json/pom.xml      |   3 +-
 .../dubbo-serialization-protostuff/pom.xml         |   3 +-
 .../serialize/protostuff/utils/WrapperUtils.java   |   2 +-
 .../dubbo-serialization-test/pom.xml               |   3 +-
 .../serialize/hessian2/Hessian2PersonOkTest.java   |   1 +
 .../support/GenericProtobufObjectOutputTest.java   |   1 +
 .../protostuff/ProtostuffObjectOutputTest.java     |  10 +-
 .../support/SerializableClassRegistryTest.java     |   3 +-
 dubbo-serialization/pom.xml                        |   1 +
 237 files changed, 2108 insertions(+), 1932 deletions(-)

diff --cc dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
index e88d9ac,ab20a6f..fbc523a
--- a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
+++ b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
@@@ -264,8 -256,8 +260,7 @@@ public class DubboBootstrap 
          return this;
      }
  
 -
      // {@link ServiceConfig} correlative methods
- 
      public <S> DubboBootstrap service(Consumer<ServiceBuilder<S>> consumerBuilder) {
          return service(DEFAULT_SERVICE_ID, consumerBuilder);
      }
@@@ -281,8 -273,8 +276,7 @@@
          return this;
      }
  
 -
      // {@link Reference} correlative methods
- 
      public <S> DubboBootstrap reference(Consumer<ReferenceBuilder<S>> consumerBuilder) {
          return reference(DEFAULT_REFERENCE_ID, consumerBuilder);
      }
@@@ -298,8 -290,8 +292,7 @@@
          return this;
      }
  
 -
      // {@link ProviderConfig} correlative methods
- 
      public DubboBootstrap provider(Consumer<ProviderBuilder> builderConsumer) {
          return provider(DEFAULT_PROVIDER_ID, builderConsumer);
      }
@@@ -319,8 -311,8 +312,7 @@@
          return this;
      }
  
 -
      // {@link ConsumerConfig} correlative methods
- 
      public DubboBootstrap consumer(Consumer<ConsumerBuilder> builderConsumer) {
          return consumer(DEFAULT_CONSUMER_ID, builderConsumer);
      }
@@@ -571,14 -560,11 +563,13 @@@
          return new ConsumerBuilder().id(id);
      }
  
 -
      /* serve for builder apis, end */
- 
      private void startMetadataReport() {
 -        ApplicationConfig applicationConfig = configManager.getApplication().orElseThrow(() -> new IllegalStateException("There's no ApplicationConfig specified."));
 +        ApplicationConfig applicationConfig = configManager.getApplication().orElseThrow(
 +                () -> new IllegalStateException("There's no ApplicationConfig specified.")
 +        );
  
 +        String metadataType = applicationConfig.getMetadata();
          // FIXME, multiple metadata config support.
          Collection<MetadataReportConfig> metadataReportConfigs = configManager.getMetadataConfigs();
          if (CollectionUtils.isEmpty(metadataReportConfigs)) {
@@@ -668,52 -653,25 +659,56 @@@
          serviceConfig.export();
      }
  
+     public boolean isOnlyRegisterProvider() {
+         return onlyRegisterProvider;
+     }
+ 
 -    private void registerServiceInstance(List<URL> exportedURLs) {
 +    private void registerServiceInstance(ApplicationConfig applicationConfig) {
 +        ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
 +        Set<String> protocols = loader.getLoadedExtensions();
 +        if (CollectionUtils.isEmpty(protocols)) {
 +            throw new IllegalStateException("There should has at least one Protocol specified.");
 +        }
 +
 +        String protocol = findOneProtocolForServiceInstance(protocols);
  
 -        exportedURLs
 -                .stream()
 -                .findFirst()
 -                .ifPresent(url -> {
 -                    String serviceName = url.getParameter(APPLICATION_KEY);
 -                    String host = url.getHost();
 -                    int port = url.getPort();
 +        Protocol protocolInstance = loader.getExtension(protocol);
  
 -                    ServiceInstance serviceInstance = initServiceInstance(serviceName, host, port);
 +        String serviceName = applicationConfig.getName();
 +        // TODO, only support exporting one server
 +        ProtocolServer server = protocolInstance.getServers().get(0);
 +        String[] address = server.getAddress().split(GROUP_CHAR_SEPERATOR);
 +        String host = address[0];
 +        int port = Integer.parseInt(address[1]);
  
 -                    getServiceDiscoveries().forEach(serviceDiscovery -> serviceDiscovery.register(serviceInstance));
 +        ServiceInstance serviceInstance = initServiceInstance(
 +                serviceName,
 +                host,
 +                port,
 +                applicationConfig.getMetadata() == null ? METADATA_DEFAULT : applicationConfig.getMetadata()
 +        );
  
 -                });
 +        getServiceDiscoveries().forEach(serviceDiscovery -> serviceDiscovery.register(serviceInstance));
 +    }
 +
 +    /**
 +     * If use rest protocol if there's one, otherwise, choose the first one available.
 +     *
 +     * @return
 +     */
 +    private String findOneProtocolForServiceInstance(Set<String> protocols) {
 +        String result = null;
 +        for (String protocol : protocols) {
 +            if ("rest".equals(protocol)) {
 +                result = protocol;
 +                break;
 +            }
 +        }
 +
 +        if (result == null) {
 +            result = protocols.iterator().next();
 +        }
 +        return result;
      }
  
      private void unregisterServiceInstance() {
diff --cc dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java
index 8c3c9d5,188312e..4887457
--- 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
@@@ -48,10 -47,8 +48,10 @@@ public class ExportedServicesRevisionMe
  
      @Override
      protected String buildMetadataValue(ServiceInstance serviceInstance) {
 -        WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension();
 +        WritableMetadataService writableMetadataService = WritableMetadataService.getExtension(
 +                serviceInstance.getMetadata().get(METADATA_KEY)
 +        );
-         List<String> exportedURLs = writableMetadataService.getExportedURLs();
+         SortedSet<String> exportedURLs = writableMetadataService.getExportedURLs();
          Object[] data = exportedURLs.stream()
                  .map(URL::valueOf)                       // String to URL
                  .map(URL::getServiceInterface)           // get the service interface
diff --cc dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
index ed86919,fadc9c4..cf5cc51
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
@@@ -22,9 -22,8 +22,9 @@@ import org.apache.dubbo.metadata.Writab
  import org.apache.dubbo.registry.client.ServiceInstance;
  import org.apache.dubbo.registry.client.ServiceInstanceMetadataCustomizer;
  
- import java.util.List;
+ import java.util.SortedSet;
  
 +import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
  import static org.apache.dubbo.metadata.MetadataService.toURLs;
  import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_KEY;
  import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataServiceParameter;


[dubbo] 04/04: Merge remote-tracking branch 'origin/cloud-native' into cloud-native

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 05ce0879067ff6010362049aed81b5f3def89c4f
Merge: 2245cf7 4a3f8ab
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri Aug 9 10:40:02 2019 +0800

    Merge remote-tracking branch 'origin/cloud-native' into cloud-native

 dubbo-all/pom.xml                                  |  2 +-
 .../ConfigurableMetadataServiceExporter.java       |  4 ++
 .../dubbo/metadata/MetadataServiceExporter.java    |  1 +
 .../dubbo/metadata/WritableMetadataService.java    |  9 ++++
 .../store/InMemoryWritableMetadataService.java     | 57 +++++++++++++++++-----
 .../store/RemoteWritableMetadataService.java       | 18 ++++++-
 .../DefaultMetadataServiceProxyFactory.java        | 42 ----------------
 .../metadata/MetadataServiceProxyFactory.java      | 51 -------------------
 .../metadata/RefreshServiceMetadataCustomizer.java | 24 +++++++++
 ...dubbo.registry.client.ServiceInstanceCustomizer |  3 +-
 10 files changed, 103 insertions(+), 108 deletions(-)



[dubbo] 01/04: Change how service instance is created.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 550b40461197fbd9d1e6dc7ba5cb6ade8d7be77f
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Aug 8 16:03:27 2019 +0800

    Change how service instance is created.
---
 dubbo-bootstrap/pom.xml                            |   7 ++
 .../org/apache/dubbo/bootstrap/DubboBootstrap.java | 139 +++++++++++++--------
 .../bootstrap/DubboServiceProviderBootstrap.java   |   3 +-
 .../wrapper/CompositeDynamicConfiguration.java     |   2 +-
 .../apache/dubbo/config/AbstractServiceConfig.java |   2 +-
 .../org/apache/dubbo/config/RegistryConfig.java    |  32 +++--
 .../dubbo/config/builders/ConfigCenterBuilder.java |   1 -
 .../apache/dubbo/config/context/ConfigManager.java |   2 +-
 .../ConfigurableMetadataServiceExporter.java       |   1 +
 .../dubbo/config/DubboProviderBootstrap.java       |   5 +-
 .../org/apache/dubbo/config/mock/MockProtocol.java |   8 ++
 .../apache/dubbo/config/mock/MockProtocol2.java    |   8 ++
 .../apache/dubbo/config/mock/MockTransporter.java  |   6 +-
 .../src/main/resources/META-INF/compat/dubbo.xsd   |  10 ++
 .../src/main/resources/META-INF/dubbo.xsd          |  10 ++
 .../dubbo/metadata/WritableMetadataService.java    |   1 +
 .../client/AbstractServiceDiscoveryFactory.java    |  71 +++++++++++
 .../EventPublishingServiceDiscoveryFactory.java    |  47 -------
 .../registry/client/ServiceDiscoveryFactory.java   |  17 +--
 ...ExportedServicesRevisionMetadataCustomizer.java |   5 +-
 ...MetadataServiceURLParamsMetadataCustomizer.java |   5 +-
 .../registry/integration/RegistryProtocol.java     |   6 +
 .../registry/support/AbstractRegistryFactory.java  |   1 -
 .../registry/support/ServiceOrientedRegistry.java  |   5 +-
 ...e.dubbo.registry.client.ServiceDiscoveryFactory |   1 -
 .../client/InMemoryServiceDiscoveryFactory.java    |   4 +-
 .../client/ServiceDiscoveryFactoryTest.java        |  55 --------
 .../registry/etcd/EtcdServiceDiscoveryFactory.java |   6 +-
 .../nacos/NacosServiceDiscoveryFactory.java        |   5 +-
 .../ZookeeperServiceDiscoveryFactory.java          |   5 +-
 .../java/org/apache/dubbo/remoting/Channel.java    |   4 +-
 .../java/org/apache/dubbo/remoting/Endpoint.java   |   2 +-
 .../remoting/{Server.java => RemotingServer.java}  | 116 ++++++++---------
 .../org/apache/dubbo/remoting/Transporter.java     |   2 +-
 .../org/apache/dubbo/remoting/Transporters.java    |   4 +-
 .../dubbo/remoting/exchange/ExchangeServer.java    |   4 +-
 .../support/header/HeaderExchangeServer.java       |   8 +-
 .../dubbo/remoting/transport/AbstractServer.java   |   8 +-
 .../dubbo/remoting/transport/ServerDelegate.java   |  12 +-
 .../transport/grizzly/GrizzlyTransporter.java      |   4 +-
 .../org/apache/dubbo/remoting/http/HttpServer.java |   3 +-
 .../remoting/http/support/AbstractHttpServer.java  |  48 +++++++
 .../remoting/transport/mina/MinaTransporter.java   |   4 +-
 .../remoting/transport/netty/NettyServer.java      |   4 +-
 .../remoting/transport/netty/NettyTransporter.java |   4 +-
 .../transport/netty/ClientReconnectTest.java       |   8 +-
 .../remoting/transport/netty/NettyClientTest.java  |   6 +-
 .../remoting/transport/netty4/NettyServer.java     |   4 +-
 .../transport/netty4/NettyTransporter.java         |   4 +-
 .../transport/netty4/ClientReconnectTest.java      |   8 +-
 .../transport/netty4/NettyTransporterTest.java     |   4 +-
 .../java/org/apache/dubbo/remoting/p2p/Peer.java   |   4 +-
 .../exchange/support/AbstractExchangeGroup.java    |   4 +-
 .../dubbo/remoting/p2p/support/AbstractGroup.java  |   8 +-
 .../dubbo/remoting/p2p/support/ServerPeer.java     |   4 +-
 .../main/java/org/apache/dubbo/rpc/Protocol.java   |   9 ++
 .../java/org/apache/dubbo/rpc/ProtocolServer.java  |  33 +++--
 .../dubbo/rpc/protocol/AbstractProtocol.java       |  12 ++
 .../dubbo/rpc/protocol/AbstractProxyProtocol.java  |  38 ++++++
 .../dubbo/rpc/protocol/ProtocolFilterWrapper.java  |   6 +
 .../rpc/protocol/ProtocolListenerWrapper.java      |   9 +-
 .../dubbo/rpc/protocol/dubbo/DubboProtocol.java    |  22 ++--
 .../rpc/protocol/dubbo/DubboProtocolServer.java    |  62 +++++++++
 .../protocol/dubbo/status/ServerStatusChecker.java |  10 +-
 .../protocol/dubbo/telnet/PortTelnetHandler.java   |  12 +-
 .../rpc/protocol/dubbo/support/ProtocolUtils.java  |   8 +-
 .../rpc/protocol/hessian/HessianProtocol.java      |  25 ++--
 .../dubbo/rpc/protocol/http/HttpProtocol.java      |  14 +--
 .../rpc/protocol/jsonrpc/JsonRpcProtocol.java      |  21 ++--
 ...RestServer.java => BaseRestProtocolServer.java} |   2 +-
 .../dubbo/rpc/protocol/rest/DubboHttpServer.java   |   4 +-
 ...ttyServer.java => NettyRestProtocolServer.java} |   6 +-
 .../dubbo/rpc/protocol/rest/RestProtocol.java      |  16 ++-
 .../{RestServer.java => RestProtocolServer.java}   |   4 +-
 .../dubbo/rpc/protocol/rest/RestServerFactory.java |   4 +-
 .../dubbo/rpc/protocol/thrift/ThriftProtocol.java  |  58 +++++++--
 .../protocol/webservice/WebServiceProtocol.java    |  15 +--
 .../xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java    |  15 ++-
 78 files changed, 727 insertions(+), 429 deletions(-)

diff --git a/dubbo-bootstrap/pom.xml b/dubbo-bootstrap/pom.xml
index 77af3e2..6f70916 100644
--- a/dubbo-bootstrap/pom.xml
+++ b/dubbo-bootstrap/pom.xml
@@ -101,6 +101,13 @@
 
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-hessian</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-remoting-netty4</artifactId>
             <version>${project.parent.version}</version>
             <scope>test</scope>
diff --git a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
index 394e345..e88d9ac 100644
--- a/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
+++ b/dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
@@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.Environment;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 import org.apache.dubbo.common.config.configcenter.wrapper.CompositeDynamicConfiguration;
-import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
@@ -49,10 +49,12 @@ import org.apache.dubbo.event.EventDispatcher;
 import org.apache.dubbo.event.EventListener;
 import org.apache.dubbo.metadata.WritableMetadataService;
 import org.apache.dubbo.metadata.store.RemoteWritableMetadataService;
+import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.support.ServiceOrientedRegistry;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -67,16 +69,17 @@ import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 
 import static java.util.Arrays.asList;
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;
 import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.getDynamicConfiguration;
-import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPERATOR;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_DEFAULT;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_REMOTE;
 import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
 import static org.apache.dubbo.config.context.ConfigManager.getInstance;
-import static org.apache.dubbo.registry.support.AbstractRegistryFactory.getRegistries;
 import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
 
 /**
@@ -257,7 +260,7 @@ public class DubboBootstrap {
     }
 
     public DubboBootstrap protocols(List<ProtocolConfig> protocolConfigs) {
-        configManager.addProtocols(protocolConfigs, true);
+        configManager.addProtocols(protocolConfigs);
         return this;
     }
 
@@ -402,7 +405,7 @@ public class DubboBootstrap {
             }
         });
 
-        configManager.addProtocols(tmpProtocols, true);
+        configManager.addProtocols(tmpProtocols);
     }
 
     /**
@@ -419,31 +422,28 @@ public class DubboBootstrap {
             return;
         }
 
-        configManager.getRegistries().forEach(registryConfig -> {
-            String protocol = registryConfig.getProtocol();
-            String id = "config-center-" + protocol + "-" + registryConfig.getPort();
-            ConfigCenterConfig cc = new ConfigCenterConfig();
-            cc.setId(id);
-            cc.setParameters(registryConfig.getParameters() == null ?
-                    new HashMap<>() :
-                    new HashMap<>(registryConfig.getParameters()));
-            cc.getParameters().put(CLIENT_KEY,registryConfig.getClient());
-            cc.setProtocol(registryConfig.getProtocol());
-            cc.setAddress(registryConfig.getAddress());
-            cc.setNamespace(registryConfig.getGroup());
-            cc.setHighestPriority(false);
-            configManager.addConfigCenter(cc);
-        });
+        configManager.getDefaultRegistries().stream()
+                .filter(registryConfig -> registryConfig.getUseAsConfigCenter() == null || registryConfig.getUseAsConfigCenter())
+                .forEach(registryConfig -> {
+                    String protocol = registryConfig.getProtocol();
+                    String id = "config-center-" + protocol + "-" + registryConfig.getPort();
+                    ConfigCenterConfig cc = new ConfigCenterConfig();
+                    cc.setId(id);
+                    cc.setParameters(registryConfig.getParameters() == null ?
+                            new HashMap<>() :
+                            new HashMap<>(registryConfig.getParameters()));
+                    cc.getParameters().put(CLIENT_KEY, registryConfig.getClient());
+                    cc.setProtocol(registryConfig.getProtocol());
+                    cc.setAddress(registryConfig.getAddress());
+                    cc.setNamespace(registryConfig.getGroup());
+                    cc.setHighestPriority(false);
+                    configManager.addConfigCenter(cc);
+                });
         startConfigCenter();
     }
 
-    private List<ServiceDiscovery> getServiceDiscoveries() {
-        return getRegistries()
-                .stream()
-                .filter(registry -> ServiceOrientedRegistry.class.isInstance(registry))
-                .map(registry -> ServiceOrientedRegistry.class.cast(registry))
-                .map(ServiceOrientedRegistry::getServiceDiscovery)
-                .collect(Collectors.toList());
+    private Collection<ServiceDiscovery> getServiceDiscoveries() {
+        return AbstractServiceDiscoveryFactory.getDiscoveries();
     }
 
     /**
@@ -464,16 +464,18 @@ public class DubboBootstrap {
                  * export {@link MetadataService}
                  */
                 // TODO, only export to default registry?
-                List<URL> exportedURLs = exportMetadataService(
-                        configManager.getApplication().orElseThrow(() -> new IllegalStateException("ApplicationConfig cannot be null")),
-                        configManager.getRegistries(),
-                        configManager.getProtocols()
-                );
-
+                ApplicationConfig applicationConfig = configManager.getApplication().orElseThrow(() -> new IllegalStateException("ApplicationConfig cannot be null"));
+                if (!METADATA_REMOTE.equals(applicationConfig.getMetadata())) {
+                    exportMetadataService(
+                            applicationConfig,
+                            configManager.getRegistries(),
+                            configManager.getProtocols()
+                    );
+                }
                 /**
                  * Register the local {@link ServiceInstance}
                  */
-                registerServiceInstance(exportedURLs);
+                registerServiceInstance(applicationConfig);
             }
 
             started = true;
@@ -572,12 +574,15 @@ public class DubboBootstrap {
     /* serve for builder apis, end */
 
     private void startMetadataReport() {
-        ApplicationConfig applicationConfig = configManager.getApplication().orElseThrow(() -> new IllegalStateException("There's no ApplicationConfig specified."));
+        ApplicationConfig applicationConfig = configManager.getApplication().orElseThrow(
+                () -> new IllegalStateException("There's no ApplicationConfig specified.")
+        );
 
+        String metadataType = applicationConfig.getMetadata();
         // FIXME, multiple metadata config support.
         Collection<MetadataReportConfig> metadataReportConfigs = configManager.getMetadataConfigs();
         if (CollectionUtils.isEmpty(metadataReportConfigs)) {
-            if (CommonConstants.METADATA_REMOTE.equals(applicationConfig.getMetadata())) {
+            if (METADATA_REMOTE.equals(metadataType)) {
                 throw new IllegalStateException("No MetadataConfig found, you must specify the remote Metadata Center address when set 'metadata=remote'.");
             }
             return;
@@ -588,7 +593,7 @@ public class DubboBootstrap {
         }
 
         RemoteWritableMetadataService remoteMetadataService =
-                (RemoteWritableMetadataService) WritableMetadataService.getExtension(applicationConfig.getMetadata());
+                (RemoteWritableMetadataService) WritableMetadataService.getExtension(metadataType);
         remoteMetadataService.initMetadataReport(metadataReportConfig.toUrl());
     }
 
@@ -663,21 +668,52 @@ public class DubboBootstrap {
         serviceConfig.export();
     }
 
-    private void registerServiceInstance(List<URL> exportedURLs) {
+    private void registerServiceInstance(ApplicationConfig applicationConfig) {
+        ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
+        Set<String> protocols = loader.getLoadedExtensions();
+        if (CollectionUtils.isEmpty(protocols)) {
+            throw new IllegalStateException("There should has at least one Protocol specified.");
+        }
 
-        exportedURLs
-                .stream()
-                .findFirst()
-                .ifPresent(url -> {
-                    String serviceName = url.getParameter(APPLICATION_KEY);
-                    String host = url.getHost();
-                    int port = url.getPort();
+        String protocol = findOneProtocolForServiceInstance(protocols);
 
-                    ServiceInstance serviceInstance = initServiceInstance(serviceName, host, port);
+        Protocol protocolInstance = loader.getExtension(protocol);
 
-                    getServiceDiscoveries().forEach(serviceDiscovery -> serviceDiscovery.register(serviceInstance));
+        String serviceName = applicationConfig.getName();
+        // TODO, only support exporting one server
+        ProtocolServer server = protocolInstance.getServers().get(0);
+        String[] address = server.getAddress().split(GROUP_CHAR_SEPERATOR);
+        String host = address[0];
+        int port = Integer.parseInt(address[1]);
 
-                });
+        ServiceInstance serviceInstance = initServiceInstance(
+                serviceName,
+                host,
+                port,
+                applicationConfig.getMetadata() == null ? METADATA_DEFAULT : applicationConfig.getMetadata()
+        );
+
+        getServiceDiscoveries().forEach(serviceDiscovery -> serviceDiscovery.register(serviceInstance));
+    }
+
+    /**
+     * If use rest protocol if there's one, otherwise, choose the first one available.
+     *
+     * @return
+     */
+    private String findOneProtocolForServiceInstance(Set<String> protocols) {
+        String result = null;
+        for (String protocol : protocols) {
+            if ("rest".equals(protocol)) {
+                result = protocol;
+                break;
+            }
+        }
+
+        if (result == null) {
+            result = protocols.iterator().next();
+        }
+        return result;
     }
 
     private void unregisterServiceInstance() {
@@ -690,8 +726,9 @@ public class DubboBootstrap {
 
     }
 
-    private ServiceInstance initServiceInstance(String serviceName, String host, int port) {
+    private ServiceInstance initServiceInstance(String serviceName, String host, int port, String metadataType) {
         this.serviceInstance = new DefaultServiceInstance(serviceName, host, port);
+        this.serviceInstance.getMetadata().put(METADATA_KEY, metadataType);
         return this.serviceInstance;
     }
 
diff --git a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java
index 019a61a..15d1628 100644
--- a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java
+++ b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java
@@ -29,9 +29,10 @@ public class DubboServiceProviderBootstrap {
                 // Zookeeper in service registry type
                 .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service"))
                 // Nacos
-                .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service"))
+//                .registry("zookeeper", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service"))
 //                .registry(RegistryBuilder.newBuilder().address("etcd3://127.0.0.1:2379?registry-type=service").build())
                 .protocol(builder -> builder.port(-1).name("dubbo"))
+                .protocol(builder -> builder.port(-1).name("hessian"))
                 .service(builder -> builder.id("test").interfaceClass(EchoService.class).ref(new EchoServiceImpl()))
                 .start()
                 .await();
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
index 700a724..3a85c41 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
@@ -27,7 +27,7 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 
 /**
- * support multiple config center, simply iterating each underlying config center.
+ * support multiple config center, simply iterating each concrete config center.
  */
 public class CompositeDynamicConfiguration implements DynamicConfiguration {
 
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
index dc40e52..b7fb5c1 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
@@ -206,7 +206,7 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig {
 
     @SuppressWarnings({"unchecked"})
     public void setProtocols(List<? extends ProtocolConfig> protocols) {
-        ConfigManager.getInstance().addProtocols((List<ProtocolConfig>) protocols, false);
+        ConfigManager.getInstance().addProtocols((List<ProtocolConfig>) protocols);
         this.protocols = (List<ProtocolConfig>) protocols;
     }
 
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
index 22974b8..55a76c7 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
@@ -30,7 +30,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
 import static org.apache.dubbo.config.Constants.REGISTRIES_SUFFIX;
-import static org.apache.dubbo.config.Constants.ZOOKEEPER_PROTOCOL;
 import static org.apache.dubbo.registry.Constants.EXTRA_KEYS_KEY;
 
 /**
@@ -151,6 +150,16 @@ public class RegistryConfig extends AbstractConfig {
      */
     private String extraKeys;
 
+    /**
+     * the address work as config center or not
+     */
+    private Boolean useAsConfigCenter;
+
+    /**
+     * the address work as remote metadata center or not
+     */
+    private Boolean useAsMetadataCenter;
+
     public RegistryConfig() {
     }
 
@@ -426,12 +435,21 @@ public class RegistryConfig extends AbstractConfig {
     }
 
     @Parameter(excluded = true)
-    public boolean isZookeeperProtocol() {
-        if (!isValid()) {
-            return false;
-        }
-        return ZOOKEEPER_PROTOCOL.equals(getProtocol())
-                || getAddress().startsWith(ZOOKEEPER_PROTOCOL);
+    public Boolean getUseAsConfigCenter() {
+        return useAsConfigCenter;
+    }
+
+    public void setUseAsConfigCenter(Boolean useAsConfigCenter) {
+        this.useAsConfigCenter = useAsConfigCenter;
+    }
+
+    @Parameter(excluded = true)
+    public Boolean getUseAsMetadataCenter() {
+        return useAsMetadataCenter;
+    }
+
+    public void setUseAsMetadataCenter(Boolean useAsMetadataCenter) {
+        this.useAsMetadataCenter = useAsMetadataCenter;
     }
 
     @Override
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/builders/ConfigCenterBuilder.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/builders/ConfigCenterBuilder.java
index 87ac00f..590170c 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/builders/ConfigCenterBuilder.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/builders/ConfigCenterBuilder.java
@@ -38,7 +38,6 @@ public class ConfigCenterBuilder extends AbstractBuilder<ConfigCenterConfig, Con
     private Boolean highestPriority = true;
     private Boolean check = true;
 
-    private String appName;
     private String configFile = "dubbo.properties";
     private String appConfigFile;
 
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
index 1888819..07895ec 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
@@ -228,7 +228,7 @@ public class ConfigManager {
         addIfAbsent(protocolConfig, protocols);
     }
 
-    public void addProtocols(Iterable<ProtocolConfig> protocolConfigs, boolean canBeDefault) {
+    public void addProtocols(Iterable<ProtocolConfig> protocolConfigs) {
         if (protocolConfigs != null) {
             protocolConfigs.forEach(this::addProtocol);
         }
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 8806f03..21601ad 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
@@ -79,6 +79,7 @@ public class ConfigurableMetadataServiceExporter implements MetadataServiceExpor
 
         if (!isExported()) {
 
+            // FIXME, if uses remote metadata center, does not need to export MetadataService locally.
             WritableMetadataService metadataService = WritableMetadataService.getDefaultExtension();
 
             ServiceConfig<MetadataService> serviceConfig = new ServiceConfig<>();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/DubboProviderBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/DubboProviderBootstrap.java
index ce5cd6a..9b68c68 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/DubboProviderBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/DubboProviderBootstrap.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.config;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.config.api.DemoService;
 import org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter;
@@ -67,9 +68,9 @@ public class DubboProviderBootstrap {
         // 暴露 MetadataService 服务
         exporter.export();
 
-        ServiceDiscoveryFactory factory = ServiceDiscoveryFactory.getDefaultExtension();
+        ServiceDiscoveryFactory factory = ExtensionLoader.getExtensionLoader(ServiceDiscoveryFactory.class).getAdaptiveExtension();
 
-        ServiceDiscovery serviceDiscovery = factory.create(connectionURL);
+        ServiceDiscovery serviceDiscovery = factory.getDiscovery(connectionURL);
 
         serviceDiscovery.start();
 
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java
index 7c33d9c..e5b0dc3 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol.java
@@ -21,11 +21,14 @@ import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 
 import org.mockito.Mockito;
 
+import java.util.List;
+
 public class MockProtocol implements Protocol {
 
     /* (non-Javadoc)
@@ -85,4 +88,9 @@ public class MockProtocol implements Protocol {
 
     }
 
+    @Override
+    public List<ProtocolServer> getServers() {
+        return null;
+    }
+
 }
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
index 91653d4..ec68c1a 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
@@ -21,8 +21,11 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
 
+import java.util.List;
+
 public class MockProtocol2 implements Protocol {
     public static Protocol delegate;
 
@@ -45,4 +48,9 @@ public class MockProtocol2 implements Protocol {
     public void destroy() {
         delegate.destroy();
     }
+
+    @Override
+    public List<ProtocolServer> getServers() {
+        return delegate.getServers();
+    }
 }
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockTransporter.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockTransporter.java
index 8abfe19..28bce33 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockTransporter.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockTransporter.java
@@ -21,17 +21,17 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 
 import org.mockito.Mockito;
 
 public class MockTransporter implements Transporter {
-    private Server server = Mockito.mock(Server.class);
+    private RemotingServer server = Mockito.mock(RemotingServer.class);
     private Client client = Mockito.mock(Client.class);
 
     @Override
-    public Server bind(URL url, ChannelHandler handler) throws RemotingException {
+    public RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException {
         return server;
     }
 
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
index 4331ea4..e926994 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
@@ -580,6 +580,16 @@
                 <xsd:documentation><![CDATA[ Extra Parameter Keys. ]]></xsd:documentation>
             </xsd:annotation>
         </xsd:attribute>
+        <xsd:attribute name="use-as-config-center" type="xsd:boolean">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ work as config center or not. ]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
+        <xsd:attribute name="use-as-metadata-center" type="xsd:boolean">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ work as metadata center or not. ]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
     </xsd:complexType>
 
     <xsd:complexType name="metadataReportType">
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index f7124c8..d75b51b 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -574,6 +574,16 @@
                 <xsd:documentation><![CDATA[ Extra Parameter Keys. ]]></xsd:documentation>
             </xsd:annotation>
         </xsd:attribute>
+        <xsd:attribute name="use-as-config-center" type="xsd:boolean">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ work as config center or not. ]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
+        <xsd:attribute name="use-as-metadata-center" type="xsd:boolean">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ work as metadata center or not. ]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
     </xsd:complexType>
 
     <xsd:complexType name="metadataReportType">
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
index f1a1ea4..478bd93 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
@@ -91,4 +91,5 @@ public interface WritableMetadataService extends MetadataService {
         return getExtensionLoader(WritableMetadataService.class).getExtension(name);
     }
 
+
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java
new file mode 100644
index 0000000..c9c6ec0
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.registry.client;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public abstract class AbstractServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+
+    private static final Logger logger = LoggerFactory.getLogger(AbstractServiceDiscoveryFactory.class);
+
+    private static ConcurrentMap<String, ServiceDiscovery> discoveries = new ConcurrentHashMap<>();
+
+    public static Collection<ServiceDiscovery> getDiscoveries() {
+        return Collections.unmodifiableCollection(discoveries.values());
+    }
+
+    /**
+     * Close all created registries
+     */
+    public static void destroyAll() {
+        if (logger.isInfoEnabled()) {
+            logger.info("Closing all ServiceDicovery instances: " + getDiscoveries());
+        }
+
+        for (ServiceDiscovery discovery : getDiscoveries()) {
+            try {
+                discovery.stop();
+            } catch (Throwable e) {
+                logger.error("Error trying to close ServiceDiscovery instance.", e);
+            }
+        }
+        discoveries.clear();
+    }
+
+    /**
+     * @param url "zookeeper://ip:port/RegistryService?xxx"
+     * @return
+     */
+    @Override
+    public ServiceDiscovery getDiscovery(URL url) {
+        String key = url.toServiceStringWithoutResolving();
+
+        return discoveries.computeIfAbsent(key, k -> {
+            ServiceDiscovery discovery = createDiscovery(url);
+            return new EventPublishingServiceDiscovery(discovery);
+        });
+    }
+
+    protected abstract ServiceDiscovery createDiscovery(URL url);
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/EventPublishingServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/EventPublishingServiceDiscoveryFactory.java
deleted file mode 100644
index 00d8bb6..0000000
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/EventPublishingServiceDiscoveryFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.apache.dubbo.registry.client;/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.SPI;
-
-import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
-
-/**
- * The factory class to create an instance of {@link ServiceDiscoveryFactory} based on Event-Publishing as the default
- * {@link SPI} implementation
- *
- * @see ServiceDiscoveryFactory
- * @see EventPublishingServiceDiscovery
- * @see ServiceDiscovery
- * @since 2.7.4
- */
-public class EventPublishingServiceDiscoveryFactory implements ServiceDiscoveryFactory {
-
-    private static final Class<ServiceDiscoveryFactory> FACTORY_CLASS = ServiceDiscoveryFactory.class;
-
-    @Override
-    public ServiceDiscovery create(URL connectionURL) {
-        String protocol = connectionURL.getProtocol();
-        ServiceDiscoveryFactory serviceDiscoveryFactory = loadFactoryByProtocol(protocol);
-        ServiceDiscovery originalServiceDiscovery = serviceDiscoveryFactory.create(connectionURL);
-        return new EventPublishingServiceDiscovery(originalServiceDiscovery);
-    }
-
-    protected ServiceDiscoveryFactory loadFactoryByProtocol(String protocol) {
-        return getExtensionLoader(FACTORY_CLASS).getExtension(protocol);
-    }
-}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java
index a48b9a8..20257f4 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java
@@ -17,17 +17,16 @@
 package org.apache.dubbo.registry.client;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.SPI;
 
-import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
-
 /**
  * The Factory interface to create an instance of {@link ServiceDiscovery}
  *
  * @see ServiceDiscovery
  * @since 2.7.4
  */
-@SPI("event-publishing")
+@SPI("zookeeper")
 public interface ServiceDiscoveryFactory {
 
     /**
@@ -36,14 +35,6 @@ public interface ServiceDiscoveryFactory {
      * @param connectionURL the  {@link URL connection url}
      * @return an instance of {@link ServiceDiscovery}
      */
-    ServiceDiscovery create(URL connectionURL);
-
-    /**
-     * Get the default extension of {@link ServiceDiscoveryFactory}
-     *
-     * @return non-null
-     */
-    static ServiceDiscoveryFactory getDefaultExtension() {
-        return getExtensionLoader(ServiceDiscoveryFactory.class).getDefaultExtension();
-    }
+    @Adaptive({"protocol"})
+    ServiceDiscovery getDiscovery(URL connectionURL);
 }
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 920096a..8c3c9d5 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
@@ -29,6 +29,7 @@ import java.util.List;
 
 import static java.lang.String.valueOf;
 import static java.util.Objects.hash;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
 import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_KEY;
 
 /**
@@ -47,7 +48,9 @@ public class ExportedServicesRevisionMetadataCustomizer extends ServiceInstanceM
 
     @Override
     protected String buildMetadataValue(ServiceInstance serviceInstance) {
-        WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension();
+        WritableMetadataService writableMetadataService = WritableMetadataService.getExtension(
+                serviceInstance.getMetadata().get(METADATA_KEY)
+        );
         List<String> exportedURLs = writableMetadataService.getExportedURLs();
         Object[] data = exportedURLs.stream()
                 .map(URL::valueOf)                       // String to URL
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
index 754a275..ed86919 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.registry.client.ServiceInstanceMetadataCustomizer;
 
 import java.util.List;
 
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
 import static org.apache.dubbo.metadata.MetadataService.toURLs;
 import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_KEY;
 import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataServiceParameter;
@@ -45,7 +46,9 @@ public class MetadataServiceURLParamsMetadataCustomizer extends ServiceInstanceM
     @Override
     public String buildMetadataValue(ServiceInstance serviceInstance) {
 
-        WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension();
+        WritableMetadataService writableMetadataService = WritableMetadataService.getExtension(
+                serviceInstance.getMetadata().get(METADATA_KEY)
+        );
 
         String serviceInterface = MetadataService.class.getName();
 
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
index fbf194f..bae63ec 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
@@ -34,6 +34,7 @@ import org.apache.dubbo.registry.RegistryService;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.ProxyFactory;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.cluster.Cluster;
@@ -446,6 +447,11 @@ public class RegistryProtocol implements Protocol {
                 .removeListener(ApplicationModel.getApplication() + CONFIGURATORS_SUFFIX, providerConfigurationListener);
     }
 
+    @Override
+    public List<ProtocolServer> getServers() {
+        return protocol.getServers();
+    }
+
     //Merge the urls of configurators
     private static URL getConfigedInvokerUrl(List<Configurator> configurators, URL url) {
         if (configurators != null && configurators.size() > 0) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
index 9441b36..0458ada 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistryFactory.java
@@ -62,7 +62,6 @@ public abstract class AbstractRegistryFactory implements RegistryFactory {
     /**
      * Close all created registries
      */
-    // TODO: 2017/8/30 to move somewhere else better
     public static void destroyAll() {
         if (LOGGER.isInfoEnabled()) {
             LOGGER.info("Close all registries " + getRegistries());
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 8018eff..ba1976b 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
@@ -17,6 +17,7 @@
 package org.apache.dubbo.registry.support;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
@@ -114,8 +115,8 @@ public class ServiceOrientedRegistry extends FailbackRegistry {
     }
 
     private ServiceDiscovery buildServiceDiscovery(URL url) {
-        ServiceDiscoveryFactory serviceDiscoveryFactory = ServiceDiscoveryFactory.getDefaultExtension();
-        ServiceDiscovery serviceDiscovery = serviceDiscoveryFactory.create(url);
+        ServiceDiscoveryFactory factory = ExtensionLoader.getExtensionLoader(ServiceDiscoveryFactory.class).getAdaptiveExtension();
+        ServiceDiscovery serviceDiscovery = factory.getDiscovery(url);
         serviceDiscovery.start();
         return serviceDiscovery;
     }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
deleted file mode 100644
index 20b8e66..0000000
--- a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
+++ /dev/null
@@ -1 +0,0 @@
-event-publishing=org.apache.dubbo.registry.client.EventPublishingServiceDiscoveryFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java
index bbd3639..6264611 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java
@@ -24,10 +24,10 @@ import org.apache.dubbo.common.URL;
  * @see InMemoryServiceDiscovery
  * @since 2.7.4
  */
-public class InMemoryServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+public class InMemoryServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
 
     @Override
-    public ServiceDiscovery create(URL connectionURL) {
+    public ServiceDiscovery createDiscovery(URL connectionURL) {
         return new InMemoryServiceDiscovery();
     }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactoryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactoryTest.java
deleted file mode 100644
index 01c2fbd..0000000
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactoryTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.registry.client;
-
-import org.apache.dubbo.common.URL;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.apache.dubbo.common.URL.valueOf;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-/**
- * {@link ServiceDiscoveryFactory} Test
- *
- * @since 2.7.4
- */
-public class ServiceDiscoveryFactoryTest {
-
-    private static final URL dubboURL = valueOf("dubbo://localhost:20880");
-
-    private static final URL inMemoryURL = valueOf("in-memory://localhost:12345");
-
-    private ServiceDiscoveryFactory serviceDiscoveryFactory;
-
-    @BeforeEach
-    public void init() {
-        serviceDiscoveryFactory = ServiceDiscoveryFactory.getDefaultExtension();
-    }
-
-    @Test
-    public void testClass() {
-        assertEquals(EventPublishingServiceDiscoveryFactory.class, serviceDiscoveryFactory.getClass());
-    }
-
-    @Test
-    public void testCreate() {
-        ServiceDiscovery serviceDiscovery = serviceDiscoveryFactory.create(inMemoryURL);
-        assertEquals(EventPublishingServiceDiscovery.class, serviceDiscovery.getClass());
-    }
-}
diff --git a/dubbo-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscoveryFactory.java
index 8d1e3b5..fb75006 100644
--- a/dubbo-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscoveryFactory.java
@@ -17,14 +17,14 @@
 package org.apache.dubbo.registry.etcd;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
-import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
 import org.apache.dubbo.remoting.etcd.EtcdTransporter;
 
 /**
  * 2019-07-08
  */
-public class EtcdServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+public class EtcdServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
 
     private EtcdTransporter etcdTransporter;
 
@@ -33,7 +33,7 @@ public class EtcdServiceDiscoveryFactory implements ServiceDiscoveryFactory {
     }
 
     @Override
-    public ServiceDiscovery create(URL connectionURL) {
+    public ServiceDiscovery createDiscovery(URL connectionURL) {
         return new EtcdServiceDiscovery(connectionURL, etcdTransporter);
     }
 }
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 4e5709e..e2ac08b 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
@@ -16,6 +16,7 @@ package org.apache.dubbo.registry.nacos;/*
  */
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
 
@@ -26,10 +27,10 @@ import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
  * @see ServiceDiscovery
  * @since 2.7.4
  */
-public class NacosServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+public class NacosServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
 
     @Override
-    public ServiceDiscovery create(URL connectionURL) {
+    public ServiceDiscovery createDiscovery(URL connectionURL) {
         return new NacosServiceDiscovery(connectionURL);
     }
 }
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 44488a4..4bf354d 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
@@ -17,6 +17,7 @@
 package org.apache.dubbo.registry.zookeeper;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory;
 import org.apache.dubbo.registry.client.ServiceDiscovery;
 import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
 
@@ -26,10 +27,10 @@ import org.apache.dubbo.registry.client.ServiceDiscoveryFactory;
  * @see ServiceDiscoveryFactory
  * @since 2.7.4
  */
-public class ZookeeperServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+public class ZookeeperServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
 
     @Override
-    public ServiceDiscovery create(URL connectionURL) {
+    public ServiceDiscovery createDiscovery(URL connectionURL) {
         try {
             return new ZookeeperServiceDiscovery(connectionURL);
         } catch (Exception e) {
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Channel.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Channel.java
index aa54b7a..c88cb4f 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Channel.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Channel.java
@@ -22,8 +22,8 @@ import java.net.InetSocketAddress;
  * Channel. (API/SPI, Prototype, ThreadSafe)
  *
  * @see org.apache.dubbo.remoting.Client
- * @see org.apache.dubbo.remoting.Server#getChannels()
- * @see org.apache.dubbo.remoting.Server#getChannel(InetSocketAddress)
+ * @see RemotingServer#getChannels()
+ * @see RemotingServer#getChannel(InetSocketAddress)
  */
 public interface Channel extends Endpoint {
 
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Endpoint.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Endpoint.java
index 0b69e1b..caafa9e 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Endpoint.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Endpoint.java
@@ -26,7 +26,7 @@ import java.net.InetSocketAddress;
  *
  * @see org.apache.dubbo.remoting.Channel
  * @see org.apache.dubbo.remoting.Client
- * @see org.apache.dubbo.remoting.Server
+ * @see RemotingServer
  */
 public interface Endpoint {
 
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Server.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingServer.java
similarity index 92%
rename from dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Server.java
rename to dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingServer.java
index c6ecf16..2c60d39 100755
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Server.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingServer.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.remoting;
-
-import org.apache.dubbo.common.Resetable;
-
-import java.net.InetSocketAddress;
-import java.util.Collection;
-
-/**
- * Remoting Server. (API/SPI, Prototype, ThreadSafe)
- * <p>
- * <a href="http://en.wikipedia.org/wiki/Client%E2%80%93server_model">Client/Server</a>
- *
- * @see org.apache.dubbo.remoting.Transporter#bind(org.apache.dubbo.common.URL, ChannelHandler)
- */
-public interface Server extends Endpoint, Resetable, IdleSensible {
-
-    /**
-     * is bound.
-     *
-     * @return bound
-     */
-    boolean isBound();
-
-    /**
-     * get channels.
-     *
-     * @return channels
-     */
-    Collection<Channel> getChannels();
-
-    /**
-     * get channel.
-     *
-     * @param remoteAddress
-     * @return channel
-     */
-    Channel getChannel(InetSocketAddress remoteAddress);
-
-    @Deprecated
-    void reset(org.apache.dubbo.common.Parameters parameters);
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.remoting;
+
+import org.apache.dubbo.common.Resetable;
+
+import java.net.InetSocketAddress;
+import java.util.Collection;
+
+/**
+ * Remoting Server. (API/SPI, Prototype, ThreadSafe)
+ * <p>
+ * <a href="http://en.wikipedia.org/wiki/Client%E2%80%93server_model">Client/Server</a>
+ *
+ * @see org.apache.dubbo.remoting.Transporter#bind(org.apache.dubbo.common.URL, ChannelHandler)
+ */
+public interface RemotingServer extends Endpoint, Resetable, IdleSensible {
+
+    /**
+     * is bound.
+     *
+     * @return bound
+     */
+    boolean isBound();
+
+    /**
+     * get channels.
+     *
+     * @return channels
+     */
+    Collection<Channel> getChannels();
+
+    /**
+     * get channel.
+     *
+     * @param remoteAddress
+     * @return channel
+     */
+    Channel getChannel(InetSocketAddress remoteAddress);
+
+    @Deprecated
+    void reset(org.apache.dubbo.common.Parameters parameters);
+
+}
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporter.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporter.java
index 2266b82..9bee120 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporter.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporter.java
@@ -41,7 +41,7 @@ public interface Transporter {
      * @see org.apache.dubbo.remoting.Transporters#bind(URL, ChannelHandler...)
      */
     @Adaptive({Constants.SERVER_KEY, Constants.TRANSPORTER_KEY})
-    Server bind(URL url, ChannelHandler handler) throws RemotingException;
+    RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException;
 
     /**
      * Connect to a server.
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporters.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporters.java
index 2d008af..bd64854 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporters.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporters.java
@@ -36,11 +36,11 @@ public class Transporters {
     private Transporters() {
     }
 
-    public static Server bind(String url, ChannelHandler... handler) throws RemotingException {
+    public static RemotingServer bind(String url, ChannelHandler... handler) throws RemotingException {
         return bind(URL.valueOf(url), handler);
     }
 
-    public static Server bind(URL url, ChannelHandler... handlers) throws RemotingException {
+    public static RemotingServer bind(URL url, ChannelHandler... handlers) throws RemotingException {
         if (url == null) {
             throw new IllegalArgumentException("url == null");
         }
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeServer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeServer.java
index 8bce090..8c52f47 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeServer.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeServer.java
@@ -16,7 +16,7 @@
  */
 package org.apache.dubbo.remoting.exchange;
 
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 
 import java.net.InetSocketAddress;
 import java.util.Collection;
@@ -24,7 +24,7 @@ import java.util.Collection;
 /**
  * ExchangeServer. (API/SPI, Prototype, ThreadSafe)
  */
-public interface ExchangeServer extends Server {
+public interface ExchangeServer extends RemotingServer {
 
     /**
      * get channels.
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
index c0524ab..93cd66a 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
@@ -28,7 +28,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.exchange.ExchangeChannel;
 import org.apache.dubbo.remoting.exchange.ExchangeServer;
 import org.apache.dubbo.remoting.exchange.Request;
@@ -53,7 +53,7 @@ public class HeaderExchangeServer implements ExchangeServer {
 
     protected final Logger logger = LoggerFactory.getLogger(getClass());
 
-    private final Server server;
+    private final RemotingServer server;
     private AtomicBoolean closed = new AtomicBoolean(false);
 
     private static final HashedWheelTimer IDLE_CHECK_TIMER = new HashedWheelTimer(new NamedThreadFactory("dubbo-server-idleCheck", true), 1,
@@ -61,13 +61,13 @@ public class HeaderExchangeServer implements ExchangeServer {
 
     private CloseTimerTask closeTimerTask;
 
-    public HeaderExchangeServer(Server server) {
+    public HeaderExchangeServer(RemotingServer server) {
         Assert.notNull(server, "server == null");
         this.server = server;
         startIdleCheckTask(getUrl());
     }
 
-    public Server getServer() {
+    public RemotingServer getServer() {
         return server;
     }
 
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractServer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractServer.java
index d1cbdbb..f8f867b 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractServer.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractServer.java
@@ -27,7 +27,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 
 import java.net.InetSocketAddress;
 import java.util.Collection;
@@ -37,15 +37,15 @@ import java.util.concurrent.ThreadPoolExecutor;
 import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
 import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
-import static org.apache.dubbo.remoting.Constants.IDLE_TIMEOUT_KEY;
-import static org.apache.dubbo.remoting.Constants.DEFAULT_IDLE_TIMEOUT;
 import static org.apache.dubbo.remoting.Constants.ACCEPTS_KEY;
 import static org.apache.dubbo.remoting.Constants.DEFAULT_ACCEPTS;
+import static org.apache.dubbo.remoting.Constants.DEFAULT_IDLE_TIMEOUT;
+import static org.apache.dubbo.remoting.Constants.IDLE_TIMEOUT_KEY;
 
 /**
  * AbstractServer
  */
-public abstract class AbstractServer extends AbstractEndpoint implements Server {
+public abstract class AbstractServer extends AbstractEndpoint implements RemotingServer {
 
     protected static final String SERVER_THREAD_POOL_NAME = "DubboServerHandler";
     private static final Logger logger = LoggerFactory.getLogger(AbstractServer.class);
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/ServerDelegate.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/ServerDelegate.java
index 6aeed60..49b508a 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/ServerDelegate.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/ServerDelegate.java
@@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 
 import java.net.InetSocketAddress;
 import java.util.Collection;
@@ -30,22 +30,22 @@ import java.util.Collection;
  *
  *
  */
-public class ServerDelegate implements Server {
+public class ServerDelegate implements RemotingServer {
 
-    private transient Server server;
+    private transient RemotingServer server;
 
     public ServerDelegate() {
     }
 
-    public ServerDelegate(Server server) {
+    public ServerDelegate(RemotingServer server) {
         setServer(server);
     }
 
-    public Server getServer() {
+    public RemotingServer getServer() {
         return server;
     }
 
-    public void setServer(Server server) {
+    public void setServer(RemotingServer server) {
         this.server = server;
     }
 
diff --git a/dubbo-remoting/dubbo-remoting-grizzly/src/main/java/org/apache/dubbo/remoting/transport/grizzly/GrizzlyTransporter.java b/dubbo-remoting/dubbo-remoting-grizzly/src/main/java/org/apache/dubbo/remoting/transport/grizzly/GrizzlyTransporter.java
index bac7d65..8e30dad 100644
--- a/dubbo-remoting/dubbo-remoting-grizzly/src/main/java/org/apache/dubbo/remoting/transport/grizzly/GrizzlyTransporter.java
+++ b/dubbo-remoting/dubbo-remoting-grizzly/src/main/java/org/apache/dubbo/remoting/transport/grizzly/GrizzlyTransporter.java
@@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 
 /**
@@ -31,7 +31,7 @@ public class GrizzlyTransporter implements Transporter {
     public static final String NAME = "grizzly";
 
     @Override
-    public Server bind(URL url, ChannelHandler listener) throws RemotingException {
+    public RemotingServer bind(URL url, ChannelHandler listener) throws RemotingException {
         return new GrizzlyServer(url, listener);
     }
 
diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/HttpServer.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/HttpServer.java
index 2ff7692..643fda4 100644
--- a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/HttpServer.java
+++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/HttpServer.java
@@ -18,10 +18,11 @@ package org.apache.dubbo.remoting.http;
 
 import org.apache.dubbo.common.Resetable;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingServer;
 
 import java.net.InetSocketAddress;
 
-public interface HttpServer extends Resetable {
+public interface HttpServer extends Resetable, RemotingServer {
 
     /**
      * get http handler.
diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/support/AbstractHttpServer.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/support/AbstractHttpServer.java
index ba4928d..2d87274 100644
--- a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/support/AbstractHttpServer.java
+++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/support/AbstractHttpServer.java
@@ -16,11 +16,16 @@
  */
 package org.apache.dubbo.remoting.http.support;
 
+import org.apache.dubbo.common.Parameters;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.Channel;
+import org.apache.dubbo.remoting.ChannelHandler;
+import org.apache.dubbo.remoting.RemotingException;
 import org.apache.dubbo.remoting.http.HttpHandler;
 import org.apache.dubbo.remoting.http.HttpServer;
 
 import java.net.InetSocketAddress;
+import java.util.Collection;
 
 /**
  * AbstractHttpServer
@@ -83,4 +88,47 @@ public abstract class AbstractHttpServer implements HttpServer {
         return closed;
     }
 
+    /**
+     * Following methods are extended from RemotingServer, useless for http servers
+     */
+
+    @Override
+    public boolean canHandleIdle() {
+        return false;
+    }
+
+    @Override
+    public Collection<Channel> getChannels() {
+        return null;
+    }
+
+    @Override
+    public Channel getChannel(InetSocketAddress remoteAddress) {
+        return null;
+    }
+
+    @Override
+    public void reset(Parameters parameters) {
+
+    }
+
+    @Override
+    public ChannelHandler getChannelHandler() {
+        return null;
+    }
+
+    @Override
+    public void send(Object message) throws RemotingException {
+
+    }
+
+    @Override
+    public void send(Object message, boolean sent) throws RemotingException {
+
+    }
+
+    @Override
+    public void startClose() {
+
+    }
 }
diff --git a/dubbo-remoting/dubbo-remoting-mina/src/main/java/org/apache/dubbo/remoting/transport/mina/MinaTransporter.java b/dubbo-remoting/dubbo-remoting-mina/src/main/java/org/apache/dubbo/remoting/transport/mina/MinaTransporter.java
index 4efdb13..d8739f4 100644
--- a/dubbo-remoting/dubbo-remoting-mina/src/main/java/org/apache/dubbo/remoting/transport/mina/MinaTransporter.java
+++ b/dubbo-remoting/dubbo-remoting-mina/src/main/java/org/apache/dubbo/remoting/transport/mina/MinaTransporter.java
@@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 
 public class MinaTransporter implements Transporter {
@@ -28,7 +28,7 @@ public class MinaTransporter implements Transporter {
     public static final String NAME = "mina";
 
     @Override
-    public Server bind(URL url, ChannelHandler handler) throws RemotingException {
+    public RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException {
         return new MinaServer(url, handler);
     }
 
diff --git a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
index 8d1cc3f..34bfab5 100644
--- a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
+++ b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
@@ -27,7 +27,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.transport.AbstractServer;
 import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;
 
@@ -50,7 +50,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;
 /**
  * NettyServer
  */
-public class NettyServer extends AbstractServer implements Server {
+public class NettyServer extends AbstractServer implements RemotingServer {
 
     private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);
 
diff --git a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyTransporter.java b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyTransporter.java
index f154a60..7ce2d03 100644
--- a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyTransporter.java
+++ b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyTransporter.java
@@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 
 public class NettyTransporter implements Transporter {
@@ -28,7 +28,7 @@ public class NettyTransporter implements Transporter {
     public static final String NAME = "netty3";
 
     @Override
-    public Server bind(URL url, ChannelHandler listener) throws RemotingException {
+    public RemotingServer bind(URL url, ChannelHandler listener) throws RemotingException {
         return new NettyServer(url, listener);
     }
 
diff --git a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientReconnectTest.java b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientReconnectTest.java
index d328eb0..65fa6a0 100644
--- a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientReconnectTest.java
+++ b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientReconnectTest.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.exchange.Exchangers;
 import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;
 
@@ -46,7 +46,7 @@ public class ClientReconnectTest {
             int port = NetUtils.getAvailablePort();
             Client client = startClient(port, 200);
             Assertions.assertFalse(client.isConnected());
-            Server server = startServer(port);
+            RemotingServer server = startServer(port);
             for (int i = 0; i < 100 && !client.isConnected(); i++) {
                 Thread.sleep(10);
             }
@@ -58,7 +58,7 @@ public class ClientReconnectTest {
             int port = NetUtils.getAvailablePort();
             Client client = startClient(port, 20000);
             Assertions.assertFalse(client.isConnected());
-            Server server = startServer(port);
+            RemotingServer server = startServer(port);
             for (int i = 0; i < 5; i++) {
                 Thread.sleep(200);
             }
@@ -74,7 +74,7 @@ public class ClientReconnectTest {
         return Exchangers.connect(url);
     }
 
-    public Server startServer(int port) throws RemotingException {
+    public RemotingServer startServer(int port) throws RemotingException {
         final String url = "exchange://127.0.0.1:" + port + "/client.reconnect.test?server=netty3";
         return Exchangers.bind(url, new HandlerAdapter());
     }
diff --git a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyClientTest.java b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyClientTest.java
index af4fca1..0290529 100644
--- a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyClientTest.java
+++ b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyClientTest.java
@@ -18,7 +18,7 @@ package org.apache.dubbo.remoting.transport.netty;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.exchange.ExchangeChannel;
 import org.apache.dubbo.remoting.exchange.Exchangers;
 
@@ -34,7 +34,7 @@ import java.util.List;
  * Time: 5:47 PM
  */
 public class NettyClientTest {
-    static Server server;
+    static RemotingServer server;
 
 
     @BeforeAll
@@ -73,7 +73,7 @@ public class NettyClientTest {
     @Test
     public void testServerClose() throws Exception {
         for (int i = 0; i < 100; i++) {
-            Server aServer = Exchangers.bind(URL.valueOf("exchange://localhost:" + (6000 + i) + "?server=netty3"), new TelnetServerHandler());
+            RemotingServer aServer = Exchangers.bind(URL.valueOf("exchange://localhost:" + (6000 + i) + "?server=netty3"), new TelnetServerHandler());
             aServer.close();
         }
     }
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java
index 0cdd9f7..882ecc8 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java
@@ -25,7 +25,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.transport.AbstractServer;
 import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;
 import org.apache.dubbo.remoting.utils.UrlUtils;
@@ -53,7 +53,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;
 /**
  * NettyServer.
  */
-public class NettyServer extends AbstractServer implements Server {
+public class NettyServer extends AbstractServer implements RemotingServer {
 
     private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);
     /**
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java
index fce2df1..c6e75af 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java
@@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 
 /**
@@ -31,7 +31,7 @@ public class NettyTransporter implements Transporter {
     public static final String NAME = "netty";
 
     @Override
-    public Server bind(URL url, ChannelHandler listener) throws RemotingException {
+    public RemotingServer bind(URL url, ChannelHandler listener) throws RemotingException {
         return new NettyServer(url, listener);
     }
 
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientReconnectTest.java b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientReconnectTest.java
index 3c357ce..22156fa 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientReconnectTest.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientReconnectTest.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.exchange.Exchangers;
 import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;
 
@@ -49,7 +49,7 @@ public class ClientReconnectTest {
             int port = NetUtils.getAvailablePort();
             Client client = startClient(port, 200);
             Assertions.assertFalse(client.isConnected());
-            Server server = startServer(port);
+            RemotingServer server = startServer(port);
             for (int i = 0; i < 100 && !client.isConnected(); i++) {
                 Thread.sleep(10);
             }
@@ -61,7 +61,7 @@ public class ClientReconnectTest {
             int port = NetUtils.getAvailablePort();
             Client client = startClient(port, 20000);
             Assertions.assertFalse(client.isConnected());
-            Server server = startServer(port);
+            RemotingServer server = startServer(port);
             for (int i = 0; i < 5; i++) {
                 Thread.sleep(200);
             }
@@ -77,7 +77,7 @@ public class ClientReconnectTest {
         return Exchangers.connect(url);
     }
 
-    public Server startServer(int port) throws RemotingException {
+    public RemotingServer startServer(int port) throws RemotingException {
         final String url = "exchange://127.0.0.1:" + port + "/client.reconnect.test?server=netty4";
         return Exchangers.bind(url, new HandlerAdapter());
     }
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
index 41937aa..74e263e 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
@@ -21,7 +21,7 @@ import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.transport.ChannelHandlerAdapter;
 
 import org.junit.jupiter.api.Test;
@@ -38,7 +38,7 @@ public class NettyTransporterTest {
         URL url = new URL("http", "localhost", port,
                 new String[]{Constants.BIND_PORT_KEY, String.valueOf(port)});
 
-        Server server = new NettyTransporter().bind(url, new ChannelHandlerAdapter());
+        RemotingServer server = new NettyTransporter().bind(url, new ChannelHandlerAdapter());
 
         assertThat(server.isBound(), is(true));
     }
diff --git a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/Peer.java b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/Peer.java
index b693f76..9d23eac 100644
--- a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/Peer.java
+++ b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/Peer.java
@@ -17,14 +17,14 @@
 package org.apache.dubbo.remoting.p2p;
 
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 
 /**
  * Peer. (SPI, Prototype, ThreadSafe)
  * <p>
  * <a href="http://en.wikipedia.org/wiki/Peer-to-peer">Peer-to-peer</a>
  */
-public interface Peer extends Server {
+public interface Peer extends RemotingServer {
 
     /**
      * leave.
diff --git a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/exchange/support/AbstractExchangeGroup.java b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/exchange/support/AbstractExchangeGroup.java
index 8408f65..55f1a92 100644
--- a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/exchange/support/AbstractExchangeGroup.java
+++ b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/exchange/support/AbstractExchangeGroup.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
 import org.apache.dubbo.remoting.exchange.ExchangeHandler;
 import org.apache.dubbo.remoting.exchange.ExchangeServer;
@@ -100,7 +100,7 @@ public abstract class AbstractExchangeGroup implements ExchangeGroup {
 
     @Override
     public void leave(URL url) throws RemotingException {
-        Server server = servers.remove(url);
+        RemotingServer server = servers.remove(url);
         if (server != null) {
             server.close();
         }
diff --git a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/AbstractGroup.java b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/AbstractGroup.java
index ffe5c69..0ea76f9 100644
--- a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/AbstractGroup.java
+++ b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/AbstractGroup.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.remoting.ChannelHandler;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporters;
 import org.apache.dubbo.remoting.p2p.Group;
 import org.apache.dubbo.remoting.p2p.Peer;
@@ -42,7 +42,7 @@ public abstract class AbstractGroup implements Group {
 
     protected final URL url;
 
-    protected final Map<URL, Server> servers = new ConcurrentHashMap<URL, Server>();
+    protected final Map<URL, RemotingServer> servers = new ConcurrentHashMap<URL, RemotingServer>();
 
     protected final Map<URL, Client> clients = new ConcurrentHashMap<URL, Client>();
 
@@ -80,7 +80,7 @@ public abstract class AbstractGroup implements Group {
 
     @Override
     public Peer join(URL url, ChannelHandler handler) throws RemotingException {
-        Server server = servers.get(url);
+        RemotingServer server = servers.get(url);
         if (server == null) { // TODO exist concurrent gap
             server = Transporters.bind(url, handler);
             servers.put(url, server);
@@ -91,7 +91,7 @@ public abstract class AbstractGroup implements Group {
 
     @Override
     public void leave(URL url) throws RemotingException {
-        Server server = servers.remove(url);
+        RemotingServer server = servers.remove(url);
         if (server != null) {
             server.close();
         }
diff --git a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/ServerPeer.java b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/ServerPeer.java
index cff3342..3d10907 100644
--- a/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/ServerPeer.java
+++ b/dubbo-remoting/dubbo-remoting-p2p/src/main/java/org/apache/dubbo/remoting/p2p/support/ServerPeer.java
@@ -23,7 +23,7 @@ import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Client;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.p2p.Group;
 import org.apache.dubbo.remoting.p2p.Peer;
 import org.apache.dubbo.remoting.transport.ServerDelegate;
@@ -44,7 +44,7 @@ public class ServerPeer extends ServerDelegate implements Peer {
 
     private final Group group;
 
-    public ServerPeer(Server server, Map<URL, Client> clients, Group group) {
+    public ServerPeer(RemotingServer server, Map<URL, Client> clients, Group group) {
         super(server);
         this.clients = clients;
         this.group = group;
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Protocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Protocol.java
index f5705e5..8d8d4b9 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Protocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Protocol.java
@@ -20,6 +20,8 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.SPI;
 
+import java.util.List;
+
 /**
  * Protocol. (API/SPI, Singleton, ThreadSafe)
  */
@@ -75,4 +77,11 @@ public interface Protocol {
      */
     void destroy();
 
+    /**
+     * Get all servers serving this protocol
+     *
+     * @return
+     */
+    List<ProtocolServer> getServers();
+
 }
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java
similarity index 59%
copy from dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java
copy to dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java
index bbd3639..3da2b95 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/InMemoryServiceDiscoveryFactory.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ProtocolServer.java
@@ -14,20 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.registry.client;
+package org.apache.dubbo.rpc;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingServer;
 
 /**
- * {@link InMemoryServiceDiscovery} Factory
- *
- * @see InMemoryServiceDiscovery
- * @since 2.7.4
+ * Distinct from {@link RemotingServer}, each protocol holds one or more ProtocolServers(the number usually decides by port numbers),
+ * while each ProtocolServer holds zero or one RemotingServer.
  */
-public class InMemoryServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+public interface ProtocolServer {
+
+    default RemotingServer getRemotingServer() {
+        return null;
+    }
+
+    default void setRemotingServers() {
 
-    @Override
-    public ServiceDiscovery create(URL connectionURL) {
-        return new InMemoryServiceDiscovery();
     }
+
+    String getAddress();
+
+    void setAddress();
+
+    default URL getUrl() {
+        return null;
+    }
+
+    default void reset(URL url) {
+    }
+
+    void close();
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
index ceeb92e..03fa1d3 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
@@ -24,10 +24,13 @@ import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -44,6 +47,11 @@ public abstract class AbstractProtocol implements Protocol {
 
     protected final Map<String, Exporter<?>> exporterMap = new ConcurrentHashMap<String, Exporter<?>>();
 
+    /**
+     * <host:port, ProtocolServer>
+     */
+    protected final Map<String, ProtocolServer> serverMap = new ConcurrentHashMap<>();
+
     //TODO SoftReference
     protected final Set<Invoker<?>> invokers = new ConcurrentHashSet<Invoker<?>>();
 
@@ -56,6 +64,10 @@ public abstract class AbstractProtocol implements Protocol {
         return ProtocolUtils.serviceKey(port, serviceName, serviceVersion, serviceGroup);
     }
 
+    public List<ProtocolServer> getServers() {
+        return Collections.unmodifiableList(new ArrayList<>(serverMap.values()));
+    }
+
     @Override
     public void destroy() {
         for (Invoker<?> invoker : invokers) {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
index d45f9e3..4b5c016 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
@@ -19,10 +19,13 @@ package org.apache.dubbo.rpc.protocol;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.Constants;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.ProxyFactory;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
@@ -149,4 +152,39 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol {
 
     protected abstract <T> T doRefer(Class<T> type, URL url) throws RpcException;
 
+    protected class ProxyProtocolServer implements ProtocolServer {
+
+        private RemotingServer server;
+        private String address;
+
+        public ProxyProtocolServer(RemotingServer server) {
+            this.server = server;
+        }
+
+        @Override
+        public RemotingServer getRemotingServer() {
+            return server;
+        }
+
+        @Override
+        public String getAddress() {
+            return StringUtils.isNotEmpty(address) ? address : server.getUrl().getAddress();
+        }
+
+        @Override
+        public void setAddress() {
+            this.address = address;
+        }
+
+        @Override
+        public URL getUrl() {
+            return server.getUrl();
+        }
+
+        @Override
+        public void close() {
+            server.close();
+        }
+    }
+
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java
index a7039a1..5a454a6 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java
@@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 
@@ -135,6 +136,11 @@ public class ProtocolFilterWrapper implements Protocol {
         protocol.destroy();
     }
 
+    @Override
+    public List<ProtocolServer> getServers() {
+        return protocol.getServers();
+    }
+
     /**
      * Register callback for each filter may be better, just like {@link java.util.concurrent.CompletionStage}, each callback
      * registration generates a new CompletionStage whose status is determined by the original CompletionStage.
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
index e8d2a26..5e8deb8 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java
@@ -23,16 +23,17 @@ import org.apache.dubbo.rpc.ExporterListener;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.InvokerListener;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.listener.ListenerExporterWrapper;
 import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
 
 import java.util.Collections;
+import java.util.List;
 
 import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
-
-import static org.apache.dubbo.rpc.Constants.INVOKER_LISTENER_KEY;
 import static org.apache.dubbo.rpc.Constants.EXPORTER_LISTENER_KEY;
+import static org.apache.dubbo.rpc.Constants.INVOKER_LISTENER_KEY;
 
 /**
  * ListenerProtocol
@@ -79,4 +80,8 @@ public class ProtocolListenerWrapper implements Protocol {
         protocol.destroy();
     }
 
+    @Override
+    public List<ProtocolServer> getServers() {
+        return protocol.getServers();
+    }
 }
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 529ac47..a0ae206 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
@@ -29,6 +29,7 @@ import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 import org.apache.dubbo.remoting.exchange.ExchangeChannel;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
@@ -40,6 +41,7 @@ import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
@@ -99,10 +101,6 @@ public class DubboProtocol extends AbstractProtocol {
     /**
      * <host:port,Exchanger>
      */
-    private final Map<String, ExchangeServer> serverMap = new ConcurrentHashMap<>();
-    /**
-     * <host:port,Exchanger>
-     */
     private final Map<String, List<ReferenceCountExchangeClient>> referenceClientMap = new ConcurrentHashMap<>();
     private final ConcurrentMap<String, Object> locks = new ConcurrentHashMap<>();
     private final Set<String> optimizers = new ConcurrentHashSet<>();
@@ -219,10 +217,6 @@ public class DubboProtocol extends AbstractProtocol {
         return INSTANCE;
     }
 
-    public Collection<ExchangeServer> getServers() {
-        return Collections.unmodifiableCollection(serverMap.values());
-    }
-
     public Collection<Exporter<?>> getExporters() {
         return Collections.unmodifiableCollection(exporterMap.values());
     }
@@ -315,7 +309,7 @@ public class DubboProtocol extends AbstractProtocol {
         //client can export a service which's only for server to invoke
         boolean isServer = url.getParameter(IS_SERVER_KEY, true);
         if (isServer) {
-            ExchangeServer server = serverMap.get(key);
+            ProtocolServer server = serverMap.get(key);
             if (server == null) {
                 synchronized (this) {
                     server = serverMap.get(key);
@@ -330,7 +324,7 @@ public class DubboProtocol extends AbstractProtocol {
         }
     }
 
-    private ExchangeServer createServer(URL url) {
+    private ProtocolServer createServer(URL url) {
         url = URLBuilder.from(url)
                 // send readonly event when server closes, it's enabled by default
                 .addParameterIfAbsent(CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString())
@@ -359,7 +353,7 @@ public class DubboProtocol extends AbstractProtocol {
             }
         }
 
-        return server;
+        return new DubboProtocolServer(server);
     }
 
     private void optimizeSerialization(URL url) throws RpcException {
@@ -605,12 +599,14 @@ public class DubboProtocol extends AbstractProtocol {
     @Override
     public void destroy() {
         for (String key : new ArrayList<>(serverMap.keySet())) {
-            ExchangeServer server = serverMap.remove(key);
+            ProtocolServer protocolServer = serverMap.remove(key);
 
-            if (server == null) {
+            if (protocolServer == null) {
                 continue;
             }
 
+            RemotingServer server = protocolServer.getRemotingServer();
+
             try {
                 if (logger.isInfoEnabled()) {
                     logger.info("Close dubbo server: " + server.getLocalAddress());
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java
new file mode 100644
index 0000000..d0933bc
--- /dev/null
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.protocol.dubbo;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.remoting.RemotingServer;
+import org.apache.dubbo.rpc.ProtocolServer;
+
+public class DubboProtocolServer implements ProtocolServer {
+
+    private RemotingServer server;
+    private String address;
+
+    public DubboProtocolServer(RemotingServer server) {
+        this.server = server;
+    }
+
+    @Override
+    public RemotingServer getRemotingServer() {
+        return server;
+    }
+
+    @Override
+    public String getAddress() {
+        return StringUtils.isNotEmpty(address) ? address : server.getUrl().getAddress();
+    }
+
+    @Override
+    public void setAddress() {
+        this.address = address;
+    }
+
+    @Override
+    public URL getUrl() {
+        return server.getUrl();
+    }
+
+    @Override
+    public void reset(URL url) {
+        server.reset(url);
+    }
+
+    @Override
+    public void close() {
+        server.close();
+    }
+}
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java
index ccbd646..53c6f6d 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java
@@ -19,10 +19,11 @@ package org.apache.dubbo.rpc.protocol.dubbo.status;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.status.Status;
 import org.apache.dubbo.common.status.StatusChecker;
-import org.apache.dubbo.remoting.exchange.ExchangeServer;
+import org.apache.dubbo.remoting.RemotingServer;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
 
-import java.util.Collection;
+import java.util.List;
 
 /**
  * ServerStatusChecker
@@ -32,13 +33,14 @@ public class ServerStatusChecker implements StatusChecker {
 
     @Override
     public Status check() {
-        Collection<ExchangeServer> servers = DubboProtocol.getDubboProtocol().getServers();
+        List<ProtocolServer> servers = DubboProtocol.getDubboProtocol().getServers();
         if (servers == null || servers.isEmpty()) {
             return new Status(Status.Level.UNKNOWN);
         }
         Status.Level level = Status.Level.OK;
         StringBuilder buf = new StringBuilder();
-        for (ExchangeServer server : servers) {
+        for (ProtocolServer protocolServer : servers) {
+            RemotingServer server = protocolServer.getRemotingServer();
             if (!server.isBound()) {
                 level = Status.Level.ERROR;
                 buf.setLength(0);
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/PortTelnetHandler.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/PortTelnetHandler.java
index 4965548..20a9e5a 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/PortTelnetHandler.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/PortTelnetHandler.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.remoting.exchange.ExchangeChannel;
 import org.apache.dubbo.remoting.exchange.ExchangeServer;
 import org.apache.dubbo.remoting.telnet.TelnetHandler;
 import org.apache.dubbo.remoting.telnet.support.Help;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
 
 import java.util.Collection;
@@ -53,7 +54,7 @@ public class PortTelnetHandler implements TelnetHandler {
             }
         }
         if (port == null || port.length() == 0) {
-            for (ExchangeServer server : DubboProtocol.getDubboProtocol().getServers()) {
+            for (ProtocolServer server : DubboProtocol.getDubboProtocol().getServers()) {
                 if (buf.length() > 0) {
                     buf.append("\r\n");
                 }
@@ -65,14 +66,15 @@ public class PortTelnetHandler implements TelnetHandler {
             }
         } else {
             int p = Integer.parseInt(port);
-            ExchangeServer server = null;
-            for (ExchangeServer s : DubboProtocol.getDubboProtocol().getServers()) {
+            ProtocolServer protocolServer = null;
+            for (ProtocolServer s : DubboProtocol.getDubboProtocol().getServers()) {
                 if (p == s.getUrl().getPort()) {
-                    server = s;
+                    protocolServer = s;
                     break;
                 }
             }
-            if (server != null) {
+            if (protocolServer != null) {
+                ExchangeServer server = (ExchangeServer) protocolServer.getRemotingServer();
                 Collection<ExchangeChannel> channels = server.getExchangeChannels();
                 for (ExchangeChannel c : channels) {
                     if (buf.length() > 0) {
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/ProtocolUtils.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/ProtocolUtils.java
index 8552f4a..128e6c6 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/ProtocolUtils.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/ProtocolUtils.java
@@ -18,14 +18,14 @@ package org.apache.dubbo.rpc.protocol.dubbo.support;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.remoting.exchange.ExchangeServer;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.ProxyFactory;
 import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
 
-import java.util.Collection;
+import java.util.List;
 
 /**
  * TODO Comment of ProtocolUtils
@@ -57,8 +57,8 @@ public class ProtocolUtils {
 
     public static void closeAll() {
         DubboProtocol.getDubboProtocol().destroy();
-        Collection<ExchangeServer> servers = DubboProtocol.getDubboProtocol().getServers();
-        for (ExchangeServer server : servers) {
+        List<ProtocolServer> servers = DubboProtocol.getDubboProtocol().getServers();
+        for (ProtocolServer server : servers) {
             server.close();
         }
     }
diff --git a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java
index 9e30d0d..648e0f2 100644
--- a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java
@@ -17,9 +17,10 @@
 package org.apache.dubbo.rpc.protocol.hessian;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.HttpHandler;
-import org.apache.dubbo.remoting.http.HttpServer;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
@@ -48,19 +49,17 @@ import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
 import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
 import static org.apache.dubbo.remoting.Constants.DEFAULT_EXCHANGER;
 import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-import static org.apache.dubbo.rpc.protocol.hessian.Constants.HESSIAN2_REQUEST_KEY;
 import static org.apache.dubbo.rpc.protocol.hessian.Constants.DEFAULT_HESSIAN2_REQUEST;
-import static org.apache.dubbo.rpc.protocol.hessian.Constants.HESSIAN_OVERLOAD_METHOD_KEY;
 import static org.apache.dubbo.rpc.protocol.hessian.Constants.DEFAULT_HESSIAN_OVERLOAD_METHOD;
 import static org.apache.dubbo.rpc.protocol.hessian.Constants.DEFAULT_HTTP_CLIENT;
+import static org.apache.dubbo.rpc.protocol.hessian.Constants.HESSIAN2_REQUEST_KEY;
+import static org.apache.dubbo.rpc.protocol.hessian.Constants.HESSIAN_OVERLOAD_METHOD_KEY;
 
 /**
  * http rpc support.
  */
 public class HessianProtocol extends AbstractProxyProtocol {
 
-    private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
-
     private final Map<String, HessianSkeleton> skeletonMap = new ConcurrentHashMap<String, HessianSkeleton>();
 
     private HttpBinder httpBinder;
@@ -81,10 +80,10 @@ public class HessianProtocol extends AbstractProxyProtocol {
     @Override
     protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
         String addr = getAddr(url);
-        HttpServer server = serverMap.get(addr);
-        if (server == null) {
-            server = httpBinder.bind(url, new HessianHandler());
-            serverMap.put(addr, server);
+        ProtocolServer protocolServer = serverMap.get(addr);
+        if (protocolServer == null) {
+            RemotingServer remotingServer = httpBinder.bind(url, new HessianHandler());
+            serverMap.put(addr, new ProxyProtocolServer(remotingServer));
         }
         final String path = url.getAbsolutePath();
         final HessianSkeleton skeleton = new HessianSkeleton(impl, type);
@@ -155,13 +154,13 @@ public class HessianProtocol extends AbstractProxyProtocol {
     public void destroy() {
         super.destroy();
         for (String key : new ArrayList<String>(serverMap.keySet())) {
-            HttpServer server = serverMap.remove(key);
-            if (server != null) {
+            ProtocolServer protocolServer = serverMap.remove(key);
+            if (protocolServer != null) {
                 try {
                     if (logger.isInfoEnabled()) {
-                        logger.info("Close hessian server " + server.getUrl());
+                        logger.info("Close hessian server " + protocolServer.getUrl());
                     }
-                    server.close();
+                    protocolServer.close();
                 } catch (Throwable t) {
                     logger.warn(t.getMessage(), t);
                 }
diff --git a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java
index db84d73..d914eda 100644
--- a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java
@@ -20,9 +20,10 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.Version;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.Constants;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.HttpHandler;
-import org.apache.dubbo.remoting.http.HttpServer;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
@@ -60,8 +61,6 @@ public class HttpProtocol extends AbstractProxyProtocol {
 
     public static final int DEFAULT_PORT = 80;
 
-    private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
-
     private final Map<String, HttpInvokerServiceExporter> skeletonMap = new ConcurrentHashMap<String, HttpInvokerServiceExporter>();
 
     private HttpBinder httpBinder;
@@ -82,10 +81,10 @@ public class HttpProtocol extends AbstractProxyProtocol {
     @Override
     protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
         String addr = getAddr(url);
-        HttpServer server = serverMap.get(addr);
-        if (server == null) {
-            server = httpBinder.bind(url, new InternalHandler());
-            serverMap.put(addr, server);
+        ProtocolServer protocolServer = serverMap.get(addr);
+        if (protocolServer == null) {
+            RemotingServer remotingServer = httpBinder.bind(url, new InternalHandler());
+            serverMap.put(addr, new ProxyProtocolServer(remotingServer));
         }
         final String path = url.getAbsolutePath();
         skeletonMap.put(path, createExporter(impl, type));
@@ -221,5 +220,4 @@ public class HttpProtocol extends AbstractProxyProtocol {
         }
 
     }
-
 }
diff --git a/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java b/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java
index 28dc56b..8195f7e 100644
--- a/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java
@@ -17,9 +17,10 @@
 package org.apache.dubbo.rpc.protocol.jsonrpc;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.HttpHandler;
-import org.apache.dubbo.remoting.http.HttpServer;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
@@ -45,8 +46,6 @@ public class JsonRpcProtocol extends AbstractProxyProtocol {
     public static final String ACCESS_CONTROL_ALLOW_METHODS_HEADER = "Access-Control-Allow-Methods";
     public static final String ACCESS_CONTROL_ALLOW_HEADERS_HEADER = "Access-Control-Allow-Headers";
 
-    private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<>();
-
     private final Map<String, JsonRpcServer> skeletonMap = new ConcurrentHashMap<>();
 
     private HttpBinder httpBinder;
@@ -102,10 +101,10 @@ public class JsonRpcProtocol extends AbstractProxyProtocol {
     @Override
     protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
         String addr = url.getIp() + ":" + url.getPort();
-        HttpServer server = serverMap.get(addr);
-        if (server == null) {
-            server = httpBinder.bind(url, new InternalHandler(url.getParameter("cors", false)));
-            serverMap.put(addr, server);
+        ProtocolServer protocolServer = serverMap.get(addr);
+        if (protocolServer == null) {
+            RemotingServer remotingServer = httpBinder.bind(url, new InternalHandler(url.getParameter("cors", false)));
+            serverMap.put(addr, new ProxyProtocolServer(remotingServer));
         }
         final String path = url.getAbsolutePath();
         JsonRpcServer skeleton = new JsonRpcServer(impl, type);
@@ -146,13 +145,13 @@ public class JsonRpcProtocol extends AbstractProxyProtocol {
     public void destroy() {
         super.destroy();
         for (String key : new ArrayList<>(serverMap.keySet())) {
-            HttpServer server = serverMap.remove(key);
-            if (server != null) {
+            ProtocolServer protocolServer = serverMap.remove(key);
+            if (protocolServer != null) {
                 try {
                     if (logger.isInfoEnabled()) {
-                        logger.info("Close jsonrpc server " + server.getUrl());
+                        logger.info("Close jsonrpc server " + protocolServer.getUrl());
                     }
-                    server.close();
+                    protocolServer.close();
                 } catch (Throwable t) {
                     logger.warn(t.getMessage(), t);
                 }
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
similarity index 97%
rename from dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestServer.java
rename to dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
index e3d1acc..f16967d 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestServer.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
@@ -24,7 +24,7 @@ import org.jboss.resteasy.spi.ResteasyDeployment;
 import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
 import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
 
-public abstract class BaseRestServer implements RestServer {
+public abstract class BaseRestProtocolServer implements RestProtocolServer {
 
     @Override
     public void start(URL url) {
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java
index 733b38f..e07d0a7 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpServer.java
@@ -36,7 +36,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Enumeration;
 
-public class DubboHttpServer extends BaseRestServer {
+public class DubboHttpServer extends BaseRestProtocolServer {
 
     private final HttpServletDispatcher dispatcher = new HttpServletDispatcher();
     private final ResteasyDeployment deployment = new ResteasyDeployment();
@@ -72,7 +72,7 @@ public class DubboHttpServer extends BaseRestServer {
     }
 
     @Override
-    public void stop() {
+    public void close() {
         httpServer.close();
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
similarity index 96%
rename from dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyServer.java
rename to dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
index dedf44a..b066c79 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyServer.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
@@ -34,14 +34,14 @@ import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
 import static org.apache.dubbo.remoting.Constants.DEFAULT_IO_THREADS;
 import static org.apache.dubbo.remoting.Constants.DEFAULT_PAYLOAD;
 import static org.apache.dubbo.remoting.Constants.PAYLOAD_KEY;
-import static org.apache.dubbo.rpc.protocol.rest.Constants.KEEP_ALIVE_KEY;
 import static org.apache.dubbo.rpc.protocol.rest.Constants.DEFAULT_KEEP_ALIVE;
+import static org.apache.dubbo.rpc.protocol.rest.Constants.KEEP_ALIVE_KEY;
 
 /**
  * Netty server can't support @Context injection of servlet objects since it's not a servlet container
  *
  */
-public class NettyServer extends BaseRestServer {
+public class NettyRestProtocolServer extends BaseRestProtocolServer {
 
     private final NettyJaxrsServer server = new NettyJaxrsServer();
 
@@ -62,7 +62,7 @@ public class NettyServer extends BaseRestServer {
     }
 
     @Override
-    public void stop() {
+    public void close() {
         server.stop();
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
index 40a09da..fe30443 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.servlet.BootstrapListener;
 import org.apache.dubbo.remoting.http.servlet.ServletManager;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
@@ -47,7 +48,6 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
 import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
@@ -71,8 +71,6 @@ public class RestProtocol extends AbstractProxyProtocol {
     private static final int HTTPCLIENTCONNECTIONMANAGER_CLOSEWAITTIME_MS = 1000;
     private static final int HTTPCLIENTCONNECTIONMANAGER_CLOSEIDLETIME_S = 30;
 
-    private final Map<String, RestServer> servers = new ConcurrentHashMap<>();
-
     private final RestServerFactory serverFactory = new RestServerFactory();
 
     // TODO in the future maybe we can just use a single rest client and connection manager
@@ -97,8 +95,8 @@ public class RestProtocol extends AbstractProxyProtocol {
     protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
         String addr = getAddr(url);
         Class implClass = ApplicationModel.getProviderModel(url.getPathKey()).getServiceInstance().getClass();
-        RestServer server = servers.computeIfAbsent(addr, restServer -> {
-            RestServer s = serverFactory.createServer(url.getParameter(SERVER_KEY, DEFAULT_SERVER));
+        RestProtocolServer server = (RestProtocolServer) serverMap.computeIfAbsent(addr, restServer -> {
+            RestProtocolServer s = serverFactory.createServer(url.getParameter(SERVER_KEY, DEFAULT_SERVER));
             s.start(url);
             return s;
         });
@@ -128,7 +126,7 @@ public class RestProtocol extends AbstractProxyProtocol {
 
         server.deploy(resourceDef, impl, contextPath);
 
-        final RestServer s = server;
+        final RestProtocolServer s = server;
         return () -> {
             // TODO due to dubbo's current architecture,
             // it will be called from registry protocol in the shutdown process and won't appear in logs
@@ -213,17 +211,17 @@ public class RestProtocol extends AbstractProxyProtocol {
             connectionMonitor.shutdown();
         }
 
-        for (Map.Entry<String, RestServer> entry : servers.entrySet()) {
+        for (Map.Entry<String, ProtocolServer> entry : serverMap.entrySet()) {
             try {
                 if (logger.isInfoEnabled()) {
                     logger.info("Closing the rest server at " + entry.getKey());
                 }
-                entry.getValue().stop();
+                entry.getValue().close();
             } catch (Throwable t) {
                 logger.warn("Error closing rest server", t);
             }
         }
-        servers.clear();
+        serverMap.clear();
 
         if (logger.isInfoEnabled()) {
             logger.info("Closing rest clients");
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
similarity index 91%
rename from dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServer.java
rename to dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
index 7b2f1e1..fe16f46 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServer.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
@@ -17,8 +17,9 @@
 package org.apache.dubbo.rpc.protocol.rest;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.ProtocolServer;
 
-public interface RestServer {
+public interface RestProtocolServer extends ProtocolServer {
 
     void start(URL url);
 
@@ -29,5 +30,4 @@ public interface RestServer {
 
     void undeploy(Class resourceDef);
 
-    void stop();
 }
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
index 1e5262c..6de7ba1 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
@@ -31,12 +31,12 @@ public class RestServerFactory {
         this.httpBinder = httpBinder;
     }
 
-    public RestServer createServer(String name) {
+    public RestProtocolServer createServer(String name) {
         // TODO move names to Constants
         if ("servlet".equalsIgnoreCase(name) || "jetty".equalsIgnoreCase(name) || "tomcat".equalsIgnoreCase(name)) {
             return new DubboHttpServer(httpBinder);
         } else if ("netty".equalsIgnoreCase(name)) {
-            return new NettyServer();
+            return new NettyRestProtocolServer();
         } else {
             throw new IllegalArgumentException("Unrecognized server name: " + name);
         }
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
index da8bec6..b5c492e 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
@@ -19,9 +19,11 @@ package org.apache.dubbo.rpc.protocol.thrift;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.Transporter;
 import org.apache.dubbo.remoting.exchange.ExchangeChannel;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
@@ -32,6 +34,7 @@ import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
@@ -41,8 +44,6 @@ import org.apache.dubbo.rpc.protocol.dubbo.DubboExporter;
 import java.util.ArrayList;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
 
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
@@ -59,10 +60,6 @@ public class ThriftProtocol extends AbstractProtocol {
 
     public static final String NAME = "thrift";
 
-    // ip:port -> ExchangeServer
-    private final ConcurrentMap<String, ExchangeServer> serverMap =
-            new ConcurrentHashMap<String, ExchangeServer>();
-
     private ExchangeHandler handler = new ExchangeHandlerAdapter() {
 
         @Override
@@ -146,9 +143,10 @@ public class ThriftProtocol extends AbstractProtocol {
 
         for (String key : new ArrayList<String>(serverMap.keySet())) {
 
-            ExchangeServer server = serverMap.remove(key);
+            ProtocolServer protocolServer = serverMap.remove(key);
 
-            if (server != null) {
+            if (protocolServer != null) {
+                RemotingServer server = protocolServer.getRemotingServer();
                 try {
                     if (logger.isInfoEnabled()) {
                         logger.info("Close dubbo server: " + server.getLocalAddress());
@@ -203,7 +201,7 @@ public class ThriftProtocol extends AbstractProtocol {
 
     }
 
-    private ExchangeServer getServer(URL url) {
+    private ProtocolServer getServer(URL url) {
         // enable sending readonly event when server closes by default
         url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
         String str = url.getParameter(Constants.SERVER_KEY, org.apache.dubbo.rpc.Constants.DEFAULT_REMOTING_SERVER);
@@ -225,7 +223,47 @@ public class ThriftProtocol extends AbstractProtocol {
                 throw new RpcException("Unsupported client type: " + str);
             }
         }
-        return server;
+        return new ThriftProtocolServer(server);
+    }
+
+    private class ThriftProtocolServer implements ProtocolServer {
+
+        private ExchangeServer server;
+        private String address;
+
+        public ThriftProtocolServer(ExchangeServer server) {
+            this.server = server;
+        }
+
+        @Override
+        public RemotingServer getRemotingServer() {
+            return server;
+        }
+
+        @Override
+        public String getAddress() {
+            return StringUtils.isNotEmpty(address) ? address : server.getUrl().getAddress();
+        }
+
+        @Override
+        public void setAddress() {
+            this.address = address;
+        }
+
+        @Override
+        public URL getUrl() {
+            return server.getUrl();
+        }
+
+        @Override
+        public void reset(URL url) {
+            server.reset(url);
+        }
+
+        @Override
+        public void close() {
+            server.close();
+        }
     }
 
 }
diff --git a/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java b/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java
index 08dc57c..8fda4ba 100644
--- a/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java
@@ -18,10 +18,11 @@ package org.apache.dubbo.rpc.protocol.webservice;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.Constants;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.HttpHandler;
-import org.apache.dubbo.remoting.http.HttpServer;
 import org.apache.dubbo.remoting.http.servlet.DispatcherServlet;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
@@ -45,8 +46,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
 import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
@@ -58,8 +57,6 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
 
     public static final int DEFAULT_PORT = 80;
 
-    private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
-
     private final ExtensionManagerBus bus = new ExtensionManagerBus();
 
     private final HTTPTransportFactory transportFactory = new HTTPTransportFactory();
@@ -83,10 +80,10 @@ public class WebServiceProtocol extends AbstractProxyProtocol {
     @Override
     protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
         String addr = getAddr(url);
-        HttpServer httpServer = serverMap.get(addr);
-        if (httpServer == null) {
-            httpServer = httpBinder.bind(url, new WebServiceHandler());
-            serverMap.put(addr, httpServer);
+        ProtocolServer protocolServer = serverMap.get(addr);
+        if (protocolServer == null) {
+            RemotingServer remotingServer = httpBinder.bind(url, new WebServiceHandler());
+            serverMap.put(addr, new ProxyProtocolServer(remotingServer));
         }
         final ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
         serverFactoryBean.setAddress(url.getAbsolutePath());
diff --git a/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java b/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java
index 83b36cd..0e492fd 100644
--- a/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java
@@ -17,9 +17,10 @@
 package org.apache.dubbo.xml.rpc.protocol.xmlrpc;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingServer;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.HttpHandler;
-import org.apache.dubbo.remoting.http.HttpServer;
+import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
@@ -47,8 +48,6 @@ public class XmlRpcProtocol extends AbstractProxyProtocol {
     public static final String ACCESS_CONTROL_ALLOW_METHODS_HEADER = "Access-Control-Allow-Methods";
     public static final String ACCESS_CONTROL_ALLOW_HEADERS_HEADER = "Access-Control-Allow-Headers";
 
-    private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<>();
-
     private final Map<String, XmlRpcServletServer> skeletonMap = new ConcurrentHashMap<>();
 
     private HttpBinder httpBinder;
@@ -105,10 +104,10 @@ public class XmlRpcProtocol extends AbstractProxyProtocol {
     protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
         final URL httpUrl = url.setProtocol("http");
         String addr = httpUrl.getIp() + ":" + httpUrl.getPort();
-        HttpServer server = serverMap.get(addr);
-        if (server == null) {
-            server = httpBinder.bind(httpUrl, new InternalHandler(httpUrl.getParameter("cors", false)));
-            serverMap.put(addr, server);
+        ProtocolServer protocolServer = serverMap.get(addr);
+        if (protocolServer == null) {
+            RemotingServer remotingServer = httpBinder.bind(httpUrl, new InternalHandler(httpUrl.getParameter("cors", false)));
+            serverMap.put(addr, new ProxyProtocolServer(remotingServer));
         }
         final String path = httpUrl.getAbsolutePath();
 
@@ -181,7 +180,7 @@ public class XmlRpcProtocol extends AbstractProxyProtocol {
     public void destroy() {
         super.destroy();
         for (String key : new ArrayList<>(serverMap.keySet())) {
-            HttpServer server = serverMap.remove(key);
+            ProtocolServer server = serverMap.remove(key);
             if (server != null) {
                 try {
                     if (logger.isInfoEnabled()) {