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

iluo pushed a commit to branch 2.7.0-release
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/2.7.0-release by this push:
     new 2f74354  fix #3179. Make registry, configcenter, matadata-report share 
a zooke… (#3182)
2f74354 is described below

commit 2f743547991ddf8e2b28a454f9670c0536d92297
Author: cvictory <[email protected]>
AuthorDate: Mon Jan 14 17:51:17 2019 +0800

    fix #3179. Make registry, configcenter, matadata-report share a zooke… 
(#3182)
    
    * fix #3179. Make registry, configcenter, matadata-report share a zookeeper 
connection
    
    * fix #3179. optimize registry, configcenter, matadata-report share a 
zookeeper connection
    
    * fix #3179. add licence
    
    * fix some review issue: just optimize constuctor order and refactor some 
code
    
    * modify HashMap to ConcurrentHashMap
    
    * add some comments
    
    * remove ZookeeperClientData and originalURLs
    
    * remove ZookeeperClientData and originalURLs
    
    * fix #3205 . add group into MetadataReport
    
    * remove SOURCE_URL_KEY from Constants
    
    * fix #3179 , #3205, #3218.  modify review issue; when sharing zookeeper 
connection, it should judge zookeeperClient.isConnected()
---
 .../java/org/apache/dubbo/common/Constants.java    |   2 +
 .../src/main/java/org/apache/dubbo/common/URL.java |  14 +-
 .../test/java/org/apache/dubbo/common/URLTest.java |   5 +-
 .../dubbo/config/AbstractInterfaceConfig.java      |   2 -
 .../apache/dubbo/config/MetadataReportConfig.java  |  14 ++
 .../src/main/resources/META-INF/compat/dubbo.xsd   |   6 +
 .../src/main/resources/META-INF/dubbo.xsd          |   5 +
 .../metadata/support/AbstractMetadataReport.java   |   1 +
 .../support/AbstractMetadataReportFactory.java     |   1 -
 .../zookeeper/curator/CuratorZookeeperClient.java  |  22 +-
 .../curator/CuratorZookeeperTransporter.java       |   8 +-
 .../support/AbstractZookeeperTransporter.java      | 155 ++++++++++++++
 .../zookeeper/zkclient/ZkClientWrapper.java        |   7 +-
 .../zkclient/ZkclientZookeeperClient.java          |  11 +-
 .../zkclient/ZkclientZookeeperTransporter.java     |   7 +-
 .../curator/CuratorZookeeperTransporterTest.java   |  19 +-
 .../support/AbstractZookeeperTransporterTest.java  | 237 +++++++++++++++++++++
 17 files changed, 471 insertions(+), 45 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java 
b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
index 1a2f553..c5e1248 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
@@ -482,12 +482,14 @@ public class Constants {
 
     /**
      * simple the registry for provider.
+     *
      * @since 2.7.0
      */
     public static final String SIMPLIFIED_KEY = "simplified";
 
     /**
      * After simplify the registry, should add some paramter individually for 
provider.
+     *
      * @since 2.7.0
      */
     public static final String EXTRA_KEYS_KEY = "extra-keys";
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java 
b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
index e5d8537..eb096f7 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
@@ -248,7 +248,7 @@ public /**final**/ class URL implements Serializable {
                 // see https://howdoesinternetwork.com/2013/ipv6-zone-id
                 // ignore
             } else {
-                port = Integer.parseInt(url.substring(i+1));
+                port = Integer.parseInt(url.substring(i + 1));
                 url = url.substring(0, i);
             }
         }
@@ -364,7 +364,7 @@ public /**final**/ class URL implements Serializable {
 
     /**
      * Fetch IP address for this URL.
-     *
+     * <p>
      * Pls. note that IP should be used instead of Host when to compare with 
socket's address or to search in a map
      * which use address as its key.
      *
@@ -498,6 +498,15 @@ public /**final**/ class URL implements Serializable {
         return Constants.COMMA_SPLIT_PATTERN.split(value);
     }
 
+    public List<String> getParameter(String key, List<String> defaultValue) {
+        String value = getParameter(key);
+        if (value == null || value.length() == 0) {
+            return defaultValue;
+        }
+        String[] strArray = Constants.COMMA_SPLIT_PATTERN.split(value);
+        return Arrays.asList(strArray);
+    }
+
     private Map<String, Number> getNumbers() {
         if (numbers == null) { // concurrent initialization is tolerant
             numbers = new ConcurrentHashMap<String, Number>();
@@ -1267,6 +1276,7 @@ public /**final**/ class URL implements Serializable {
             buf.append("/");
             buf.append(path);
         }
+
         if (appendParameter) {
             buildParameters(buf, true, parameters);
         }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java 
b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java
index 37696e6..cc2a5db 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java
@@ -17,7 +17,6 @@
 package org.apache.dubbo.common;
 
 import org.apache.dubbo.common.utils.CollectionUtils;
-
 import org.junit.Test;
 
 import java.io.File;
@@ -124,7 +123,7 @@ public class URLTest {
         assertEquals("home/user1/router.js", url.getPath());
         assertEquals(0, url.getParameters().size());
 
-        // Caution!! 
+        // Caution!!
         url = URL.valueOf("file://home/user1/router.js");
         //                      ^^ only tow slash!
         assertEquals("file", url.getProtocol());
@@ -680,4 +679,4 @@ public class URLTest {
         assertEquals("1.0.0", url.getParameter("version"));
         assertEquals("morgan", url.getParameter("application"));
     }
-}
\ No newline at end of file
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index b9d6173..d25dfd6 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@ -52,7 +52,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static org.apache.dubbo.common.Constants.APPLICATION_KEY;
 import static 
org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;
 import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
 
@@ -376,7 +375,6 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
             return null;
         }
         Map<String, String> map = new HashMap<String, String>();
-        map.put(APPLICATION_KEY, application.getName());
         appendParameters(map, metadataReportConfig);
         return UrlUtils.parseURL(address, map);
     }
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
index d1bb53b..a4ace7a 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java
@@ -50,6 +50,11 @@ public class MetadataReportConfig extends AbstractConfig {
     // Request timeout in milliseconds for register center
     private Integer timeout;
 
+    /**
+     * The group the metadata in . It is the same as registry
+     */
+    private String group;
+
     // Customized parameters
     private Map<String, String> parameters;
 
@@ -73,6 +78,7 @@ public class MetadataReportConfig extends AbstractConfig {
         setAddress(address);
     }
 
+    @Parameter(excluded = true)
     public String getAddress() {
         return address;
     }
@@ -160,4 +166,12 @@ public class MetadataReportConfig extends AbstractConfig {
     public boolean isValid() {
         return StringUtils.isNotEmpty(address);
     }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
 }
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 195e9a1..30e8f14 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
@@ -606,6 +606,12 @@
                 <xsd:documentation><![CDATA[ The request timeout. 
]]></xsd:documentation>
             </xsd:annotation>
         </xsd:attribute>
+        <xsd:attribute name="group" type="xsd:string" use="optional">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ The group of metadata-report. 
]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
+
         <xsd:attribute name="retry-times" type="xsd:integer" use="optional">
             <xsd:annotation>
                 <xsd:documentation><![CDATA[ if fail, retry times. 
]]></xsd:documentation>
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 c481d71..c5b890c 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
@@ -600,6 +600,11 @@
                 <xsd:documentation><![CDATA[ The request timeout. 
]]></xsd:documentation>
             </xsd:annotation>
         </xsd:attribute>
+        <xsd:attribute name="group" type="xsd:string" use="optional">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ The group of metadata-report. 
]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
 
         <xsd:attribute name="retry-times" type="xsd:integer" use="optional">
             <xsd:annotation>
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
index 9aab901..d29b636 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
@@ -329,6 +329,7 @@ public abstract class AbstractMetadataReport implements 
MetadataReport {
      * not private. just for unittest.
      */
     void publishAll() {
+        logger.info("start to publish all metadata.");
         this.doHandleMetadataCollection(allMetadataReports);
     }
 
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReportFactory.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReportFactory.java
index 392350c..f3ce5d6 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReportFactory.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReportFactory.java
@@ -38,7 +38,6 @@ public abstract class AbstractMetadataReportFactory 
implements MetadataReportFac
     @Override
     public MetadataReport getMetadataReport(URL url) {
         url = url.setPath(MetadataReport.class.getName())
-                .addParameter(Constants.INTERFACE_KEY, 
MetadataReport.class.getName())
                 .removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY);
         String key = url.toServiceString();
         // Lock the registry access process to ensure a single instance of the 
registry
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
index e1315e3..a78edda 100644
--- 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
@@ -16,19 +16,18 @@
  */
 package org.apache.dubbo.remoting.zookeeper.curator;
 
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.remoting.zookeeper.ChildListener;
-import org.apache.dubbo.remoting.zookeeper.StateListener;
-import org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient;
-
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
 import org.apache.curator.framework.api.CuratorWatcher;
 import org.apache.curator.framework.state.ConnectionState;
 import org.apache.curator.framework.state.ConnectionStateListener;
 import org.apache.curator.retry.RetryNTimes;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.remoting.zookeeper.ChildListener;
+import org.apache.dubbo.remoting.zookeeper.StateListener;
+import org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException.NoNodeException;
 import org.apache.zookeeper.KeeperException.NodeExistsException;
@@ -43,6 +42,7 @@ public class CuratorZookeeperClient extends 
AbstractZookeeperClient<CuratorWatch
     private final Charset charset = Charset.forName("UTF-8");
     private final CuratorFramework client;
 
+
     public CuratorZookeeperClient(URL url) {
         super(url);
         try {
@@ -147,6 +147,7 @@ public class CuratorZookeeperClient extends 
AbstractZookeeperClient<CuratorWatch
         }
         return false;
     }
+
     @Override
     public boolean isConnected() {
         return client.getZookeeperClient().isConnected();
@@ -156,12 +157,9 @@ public class CuratorZookeeperClient extends 
AbstractZookeeperClient<CuratorWatch
     public String doGetContent(String path) {
         try {
             byte[] dataBytes = client.getData().forPath(path);
-            if(dataBytes == null || dataBytes.length == 0){
-                return null;
-            }
-            return new String(dataBytes, charset);
-        } catch (NodeExistsException e) {
+            return (dataBytes == null || dataBytes.length == 0) ? null : new 
String(dataBytes, charset);
         } catch (NoNodeException e) {
+            // ignore NoNode Exception.
         } catch (Exception e) {
             throw new IllegalStateException(e.getMessage(), e);
         }
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java
index 363a697..b6a6c3e 100644
--- 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporter.java
@@ -18,13 +18,13 @@ package org.apache.dubbo.remoting.zookeeper.curator;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+import 
org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperTransporter;
 
-public class CuratorZookeeperTransporter implements ZookeeperTransporter {
+public class CuratorZookeeperTransporter extends AbstractZookeeperTransporter {
 
-    @Override
-    public ZookeeperClient connect(URL url) {
+    public ZookeeperClient createZookeeperClient(URL url) {
         return new CuratorZookeeperClient(url);
     }
 
+
 }
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporter.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporter.java
new file mode 100644
index 0000000..43d848a
--- /dev/null
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporter.java
@@ -0,0 +1,155 @@
+/*
+ * 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.zookeeper.support;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
+import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * AbstractZookeeperTransporter is abstract implements of ZookeeperTransporter.
+ * <p>
+ * If you want to extends this, implements createZookeeperClient.
+ */
+public abstract class AbstractZookeeperTransporter implements 
ZookeeperTransporter {
+    private static final Logger logger = 
LoggerFactory.getLogger(ZookeeperTransporter.class);
+    private final Map<String, ZookeeperClient> zookeeperClientMap = new 
ConcurrentHashMap<>();
+
+    /**
+     * share connnect for registry, metadata, etc..
+     * <p>
+     * Make sure the connection is connected.
+     *
+     * @param url
+     * @return
+     */
+    public ZookeeperClient connect(URL url) {
+        ZookeeperClient zookeeperClient;
+        List<String> addressList = getURLBackupAddress(url);
+        // The field define the zookeeper server , including protocol, host, 
port, username, password
+        if ((zookeeperClient = 
fetchAndUpdateZookeeperClientCache(addressList)) != null && 
zookeeperClient.isConnected()) {
+            logger.info("Get result from map for the first time when invoking 
zookeeperTransporter.connnect .");
+            return zookeeperClient;
+        }
+        // avoid creating too many connections, so add lock
+        synchronized (zookeeperClientMap) {
+            if ((zookeeperClient = 
fetchAndUpdateZookeeperClientCache(addressList)) != null && 
zookeeperClient.isConnected()) {
+                logger.info("Get result from map for the second time when 
invoking zookeeperTransporter.connnect .");
+                return zookeeperClient;
+            }
+
+            zookeeperClient = createZookeeperClient(createServerURL(url));
+            logger.info("Get result by creating new connection when invoking 
zookeeperTransporter.connnect .");
+            writeToClientMap(addressList, zookeeperClient);
+        }
+        return zookeeperClient;
+    }
+
+    /**
+     * @param url the url that will create zookeeper connection .
+     *            The url in AbstractZookeeperTransporter#connect parameter is 
rewritten by this one.
+     *            such as: 
zookeeper://127.0.0.1:2181/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter
+     * @return
+     */
+    protected abstract ZookeeperClient createZookeeperClient(URL url);
+
+    /**
+     * get the ZookeeperClient from cache, the ZookeeperClient must be 
connected.
+     * <p>
+     * It is not private method for unit test.
+     *
+     * @param addressList
+     * @return
+     */
+    ZookeeperClient fetchAndUpdateZookeeperClientCache(List<String> 
addressList) {
+
+        ZookeeperClient zookeeperClient = null;
+        for (String address : addressList) {
+            if ((zookeeperClient = zookeeperClientMap.get(address)) != null && 
zookeeperClient.isConnected()) {
+                break;
+            }
+        }
+        if (zookeeperClient != null && zookeeperClient.isConnected()) {
+            writeToClientMap(addressList, zookeeperClient);
+        }
+        return zookeeperClient;
+    }
+
+    /**
+     * get all zookeeper urls (such as 
:zookeeper://127.0.0.1:2181?127.0.0.1:8989,127.0.0.1:9999)
+     *
+     * @param url such 
as:zookeeper://127.0.0.1:2181?127.0.0.1:8989,127.0.0.1:9999
+     * @return such as 127.0.0.1:2181,127.0.0.1:8989,127.0.0.1:9999
+     */
+    List<String> getURLBackupAddress(URL url) {
+        List<String> addressList = new ArrayList<String>();
+        addressList.add(url.getAddress());
+
+        addressList.addAll(url.getParameter(Constants.BACKUP_KEY, 
Collections.EMPTY_LIST));
+        return addressList;
+    }
+
+    /**
+     * write address-ZookeeperClient relationship to Map
+     *
+     * @param addressList
+     * @param zookeeperClient
+     */
+    void writeToClientMap(List<String> addressList, ZookeeperClient 
zookeeperClient) {
+        for (String address : addressList) {
+            zookeeperClientMap.put(address, zookeeperClient);
+        }
+    }
+
+    /**
+     * redefine the url for zookeeper. just keep protocol, username, password, 
host, port, and individual parameter.
+     *
+     * @param url
+     * @return
+     */
+    URL createServerURL(URL url) {
+        Map<String, String> parameterMap = new HashMap<>();
+        // for CuratorZookeeperClient
+        if (url.getParameter(Constants.TIMEOUT_KEY) != null) {
+            parameterMap.put(Constants.TIMEOUT_KEY, 
url.getParameter(Constants.TIMEOUT_KEY));
+        }
+        if (url.getParameter(Constants.BACKUP_KEY) != null) {
+            parameterMap.put(Constants.BACKUP_KEY, 
url.getParameter(Constants.BACKUP_KEY));
+        }
+        return new URL(url.getProtocol(), url.getUsername(), 
url.getPassword(), url.getHost(), url.getPort(),
+                ZookeeperTransporter.class.getName(), parameterMap);
+    }
+
+    /**
+     * for unit test
+     *
+     * @return
+     */
+    Map<String, ZookeeperClient> getZookeeperClientMap() {
+        return zookeeperClientMap;
+    }
+}
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkClientWrapper.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkClientWrapper.java
index 3f873af..ae8a3ef 100644
--- 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkClientWrapper.java
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkClientWrapper.java
@@ -16,13 +16,12 @@
  */
 package org.apache.dubbo.remoting.zookeeper.zkclient;
 
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.Assert;
-
 import org.I0Itec.zkclient.IZkChildListener;
 import org.I0Itec.zkclient.IZkStateListener;
 import org.I0Itec.zkclient.ZkClient;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.Assert;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 
 import java.util.List;
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperClient.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperClient.java
index 2133952..c366400 100644
--- 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperClient.java
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperClient.java
@@ -16,6 +16,11 @@
  */
 package org.apache.dubbo.remoting.zookeeper.zkclient;
 
+
+import org.I0Itec.zkclient.IZkChildListener;
+import org.I0Itec.zkclient.IZkStateListener;
+import org.I0Itec.zkclient.exception.ZkNoNodeException;
+import org.I0Itec.zkclient.exception.ZkNodeExistsException;
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
@@ -23,11 +28,6 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.remoting.zookeeper.ChildListener;
 import org.apache.dubbo.remoting.zookeeper.StateListener;
 import org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient;
-
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkStateListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 
 import java.util.List;
@@ -63,7 +63,6 @@ public class ZkclientZookeeperClient extends 
AbstractZookeeperClient<IZkChildLis
         client.start();
     }
 
-
     @Override
     public void createPersistent(String path) {
         try {
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperTransporter.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperTransporter.java
index de5ee4b..eef25af 100644
--- 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperTransporter.java
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/zkclient/ZkclientZookeeperTransporter.java
@@ -18,12 +18,11 @@ package org.apache.dubbo.remoting.zookeeper.zkclient;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+import 
org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperTransporter;
 
-public class ZkclientZookeeperTransporter implements ZookeeperTransporter {
+public class ZkclientZookeeperTransporter extends AbstractZookeeperTransporter 
{
 
-    @Override
-    public ZookeeperClient connect(URL url) {
+    public ZookeeperClient createZookeeperClient(URL url) {
         return new ZkclientZookeeperClient(url);
     }
 
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java
index 2c9dbb9..c9339cf 100644
--- 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperTransporterTest.java
@@ -16,10 +16,10 @@
  */
 package org.apache.dubbo.remoting.zookeeper.curator;
 
+import org.apache.curator.test.TestingServer;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.curator.test.TestingServer;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -31,13 +31,22 @@ import static org.hamcrest.core.IsNull.nullValue;
 public class CuratorZookeeperTransporterTest {
     private TestingServer zkServer;
     private ZookeeperClient zookeeperClient;
+    private CuratorZookeeperTransporter curatorZookeeperTransporter;
+    private int zkServerPort;
 
     @Before
     public void setUp() throws Exception {
-        int zkServerPort = NetUtils.getAvailablePort();
+        zkServerPort = NetUtils.getAvailablePort();
         zkServer = new TestingServer(zkServerPort, true);
         zookeeperClient = new 
CuratorZookeeperTransporter().connect(URL.valueOf("zookeeper://127.0.0.1:" +
                 zkServerPort + "/service"));
+        curatorZookeeperTransporter = new CuratorZookeeperTransporter();
+    }
+
+
+    @After
+    public void tearDown() throws Exception {
+        zkServer.stop();
     }
 
     @Test
@@ -46,8 +55,4 @@ public class CuratorZookeeperTransporterTest {
         zookeeperClient.close();
     }
 
-    @After
-    public void tearDown() throws Exception {
-        zkServer.stop();
-    }
-}
\ No newline at end of file
+}
diff --git 
a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporterTest.java
 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporterTest.java
new file mode 100644
index 0000000..2431936
--- /dev/null
+++ 
b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/support/AbstractZookeeperTransporterTest.java
@@ -0,0 +1,237 @@
+/*
+ * 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.zookeeper.support;
+
+import org.apache.curator.test.TestingServer;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
+import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+import org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.IsNull.nullValue;
+
+/**
+ * AbstractZookeeperTransporterTest
+ */
+public class AbstractZookeeperTransporterTest {
+    private TestingServer zkServer;
+    private ZookeeperClient zookeeperClient;
+    private AbstractZookeeperTransporter abstractZookeeperTransporter;
+    private int zkServerPort;
+
+    @Before
+    public void setUp() throws Exception {
+        zkServerPort = NetUtils.getAvailablePort();
+        zkServer = new TestingServer(zkServerPort, true);
+        zookeeperClient = new 
CuratorZookeeperTransporter().connect(URL.valueOf("zookeeper://127.0.0.1:" +
+                zkServerPort + "/service"));
+        abstractZookeeperTransporter = new CuratorZookeeperTransporter();
+    }
+
+
+    @After
+    public void tearDown() throws Exception {
+        zkServer.stop();
+    }
+
+    @Test
+    public void testZookeeperClient() {
+        assertThat(zookeeperClient, not(nullValue()));
+        zookeeperClient.close();
+    }
+
+    @Test
+    public void testCreateServerURL() {
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828&timeout=2300");
+        URL newUrl = abstractZookeeperTransporter.createServerURL(url);
+        Assert.assertEquals(newUrl.getProtocol(), "zookeeper");
+        Assert.assertEquals(newUrl.getHost(), "127.0.0.1");
+        Assert.assertEquals(newUrl.getPort(), zkServerPort);
+        Assert.assertNull(newUrl.getUsername());
+        Assert.assertNull(newUrl.getPassword());
+        Assert.assertEquals(newUrl.getParameter(Constants.TIMEOUT_KEY, 5000), 
2300);
+        Assert.assertEquals(newUrl.getParameters().size(), 1);
+        Assert.assertEquals(newUrl.getPath(), 
ZookeeperTransporter.class.getName());
+    }
+
+
+    @Test
+    public void testCreateServerURLWhenHasUser() {
+        URL url = URL.valueOf("zookeeper://us2:[email protected]:" + zkServerPort 
+ 
"/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        URL newUrl = abstractZookeeperTransporter.createServerURL(url);
+        Assert.assertEquals(newUrl.getProtocol(), "zookeeper");
+        Assert.assertEquals(newUrl.getHost(), "127.0.0.1");
+        Assert.assertEquals(newUrl.getPort(), zkServerPort);
+        Assert.assertEquals(newUrl.getUsername(), "us2");
+        Assert.assertEquals(newUrl.getPassword(), "pw2");
+        Assert.assertEquals(newUrl.getParameters().size(), 0);
+        Assert.assertEquals(newUrl.getPath(), 
ZookeeperTransporter.class.getName());
+    }
+
+    @Test
+    public void testGetURLBackupAddress() {
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + 9099 + 
"&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        List<String> stringList = 
abstractZookeeperTransporter.getURLBackupAddress(url);
+        Assert.assertEquals(stringList.size(), 2);
+        Assert.assertEquals(stringList.get(0), "127.0.0.1:" + zkServerPort);
+        Assert.assertEquals(stringList.get(1), "127.0.0.1:9099");
+    }
+
+    @Test
+    public void testGetURLBackupAddressNoBack() {
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        List<String> stringList = 
abstractZookeeperTransporter.getURLBackupAddress(url);
+        Assert.assertEquals(stringList.size(), 1);
+        Assert.assertEquals(stringList.get(0), "127.0.0.1:" + zkServerPort);
+    }
+
+    @Test
+    public void testFetchAndUpdateZookeeperClientCache() throws Exception {
+        int zkServerPort2 = NetUtils.getAvailablePort();
+        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
+
+        int zkServerPort3 = NetUtils.getAvailablePort();
+        TestingServer zkServer3 = new TestingServer(zkServerPort3, true);
+
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zkServerPort3 
+ ",127.0.0.1:" + zkServerPort2 + 
"&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        ZookeeperClient newZookeeperClient = 
abstractZookeeperTransporter.connect(url);
+        //just for connected
+        newZookeeperClient.getContent("/dubbo/test");
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 3);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort), newZookeeperClient);
+
+        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
+        checkFetchAndUpdateCacheNotNull(url2);
+        URL url3 = 
URL.valueOf("zookeeper://127.0.0.1:8778/org.apache.dubbo.metadata.store.MetadataReport?backup=127.0.0.1:"
 + zkServerPort3 + 
"&address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
+        checkFetchAndUpdateCacheNotNull(url3);
+
+        zkServer2.stop();
+        zkServer3.stop();
+    }
+
+    private void checkFetchAndUpdateCacheNotNull(URL url) {
+        List<String> addressList = 
abstractZookeeperTransporter.getURLBackupAddress(url);
+        ZookeeperClient zookeeperClient = 
abstractZookeeperTransporter.fetchAndUpdateZookeeperClientCache(addressList);
+        Assert.assertNotNull(zookeeperClient);
+    }
+
+    @Test
+    public void testRepeatConnect() {
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
+        ZookeeperClient newZookeeperClient = 
abstractZookeeperTransporter.connect(url);
+        //just for connected
+        newZookeeperClient.getContent("/dubbo/test");
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 1);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort), newZookeeperClient);
+        Assert.assertTrue(newZookeeperClient.isConnected());
+
+        ZookeeperClient newZookeeperClient2 = 
abstractZookeeperTransporter.connect(url2);
+        //just for connected
+        newZookeeperClient2.getContent("/dubbo/test");
+        Assert.assertEquals(newZookeeperClient, newZookeeperClient2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 1);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort), newZookeeperClient);
+    }
+
+    @Test
+    public void testNotRepeatConnect() throws Exception {
+        int zkServerPort2 = NetUtils.getAvailablePort();
+        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
+
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort2 + 
"/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
+        ZookeeperClient newZookeeperClient = 
abstractZookeeperTransporter.connect(url);
+        //just for connected
+        newZookeeperClient.getContent("/dubbo/test");
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 1);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort), newZookeeperClient);
+
+        ZookeeperClient newZookeeperClient2 = 
abstractZookeeperTransporter.connect(url2);
+        //just for connected
+        newZookeeperClient2.getContent("/dubbo/test");
+        Assert.assertNotEquals(newZookeeperClient, newZookeeperClient2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort2), newZookeeperClient2);
+
+        zkServer2.stop();
+    }
+
+    @Test
+    public void testRepeatConnectForBackUpAdd() throws Exception {
+        int zkServerPort2 = NetUtils.getAvailablePort();
+        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
+
+        int zkServerPort3 = NetUtils.getAvailablePort();
+        TestingServer zkServer3 = new TestingServer(zkServerPort3, true);
+
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zkServerPort2 
+ 
"&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort2 + 
"/org.apache.dubbo.metadata.store.MetadataReport?backup=127.0.0.1:" + 
zkServerPort3 + 
"&address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
+        ZookeeperClient newZookeeperClient = 
abstractZookeeperTransporter.connect(url);
+        //just for connected
+        newZookeeperClient.getContent("/dubbo/test");
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort), newZookeeperClient);
+
+        ZookeeperClient newZookeeperClient2 = 
abstractZookeeperTransporter.connect(url2);
+        //just for connected
+        newZookeeperClient2.getContent("/dubbo/test");
+        Assert.assertEquals(newZookeeperClient, newZookeeperClient2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 3);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort2), newZookeeperClient2);
+
+        zkServer2.stop();
+        zkServer3.stop();
+    }
+
+    @Test
+    public void testRepeatConnectForNoMatchBackUpAdd() throws Exception {
+        int zkServerPort2 = NetUtils.getAvailablePort();
+        TestingServer zkServer2 = new TestingServer(zkServerPort2, true);
+
+        int zkServerPort3 = NetUtils.getAvailablePort();
+        TestingServer zkServer3 = new TestingServer(zkServerPort3, true);
+
+        URL url = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort + 
"/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zkServerPort3 
+ 
"&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT&timestamp=1547102428828");
+        URL url2 = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort2 + 
"/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true");
+        ZookeeperClient newZookeeperClient = 
abstractZookeeperTransporter.connect(url);
+        //just for connected
+        newZookeeperClient.getContent("/dubbo/test");
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort), newZookeeperClient);
+
+        ZookeeperClient newZookeeperClient2 = 
abstractZookeeperTransporter.connect(url2);
+        //just for connected
+        newZookeeperClient2.getContent("/dubbo/test");
+        Assert.assertNotEquals(newZookeeperClient, newZookeeperClient2);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().size(),
 3);
+        
Assert.assertEquals(abstractZookeeperTransporter.getZookeeperClientMap().get("127.0.0.1:"
 + zkServerPort2), newZookeeperClient2);
+
+        zkServer2.stop();
+        zkServer3.stop();
+    }
+}

Reply via email to