You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2017/12/27 02:51:27 UTC

[GitHub] weichao666 closed pull request #443: [JAV-558] pullTask,use rev to ensure data consistency and reduce service center work load

weichao666 closed pull request #443: [JAV-558] pullTask,use rev to ensure data consistency and reduce service center work load
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/443
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java
index 822bb9f72..4272e0ec9 100644
--- a/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java
+++ b/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java
@@ -170,7 +170,7 @@ private static void testCommonInvoke(String transport) {
 
     result =
         InvokerUtils.syncInvoke("pojo",
-            "0.0.1",
+            "0.0.4",
             transport,
             "server",
             "splitParam",
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/RegistryUtils.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/RegistryUtils.java
index 598e7ef28..66d0cf718 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/RegistryUtils.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/RegistryUtils.java
@@ -38,6 +38,7 @@
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.cache.InstanceCacheManager;
 import io.servicecomb.serviceregistry.client.ServiceRegistryClient;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.config.ServiceRegistryConfig;
 import io.servicecomb.serviceregistry.definition.MicroserviceDefinition;
 import io.servicecomb.serviceregistry.registry.ServiceRegistryFactory;
@@ -202,9 +203,9 @@ private static IpPort genPublishIpPort(String schema, IpPort ipPort) {
     return new IpPort(publicAddressSetting, publishPort);
   }
 
-  public static List<MicroserviceInstance> findServiceInstance(String appId, String serviceName,
-      String versionRule) {
-    return serviceRegistry.findServiceInstance(appId, serviceName, versionRule);
+  public static MicroserviceInstanceRefresh findServiceInstance(String appId, String serviceName,
+      String versionRule, String revision) {
+    return serviceRegistry.findServiceInstance(appId, serviceName, versionRule, revision);
   }
 
   // update microservice instance properties
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/ServiceRegistry.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/ServiceRegistry.java
index 0dd0224ea..91f8ad561 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/ServiceRegistry.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/ServiceRegistry.java
@@ -16,7 +16,6 @@
  */
 package io.servicecomb.serviceregistry;
 
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -24,6 +23,7 @@
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.cache.InstanceCacheManager;
 import io.servicecomb.serviceregistry.client.ServiceRegistryClient;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.consumer.AppManager;
 
 public interface ServiceRegistry {
@@ -45,8 +45,8 @@
 
   InstanceCacheManager getInstanceCacheManager();
 
-  List<MicroserviceInstance> findServiceInstance(String appId, String microserviceName,
-      String microserviceVersionRule);
+  MicroserviceInstanceRefresh findServiceInstance(String appId, String microserviceName,
+      String microserviceVersionRule, String revision);
 
   boolean updateMicroserviceProperties(Map<String, String> properties);
 
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCache.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCache.java
index 7a414b05a..d065d7c2c 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCache.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCache.java
@@ -30,6 +30,7 @@
 import io.servicecomb.foundation.common.cache.VersionedCache;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstanceStatus;
+import io.servicecomb.serviceregistry.definition.DefinitionConst;
 
 /**
  * ????????????
@@ -61,6 +62,9 @@
 
   private Object lockObj = new Object();
 
+  //cached Revision in the header
+  private String revision = DefinitionConst.DEFAULT_REVISION;
+
   /**
    * ???????
    */
@@ -135,4 +139,13 @@ public String getMicroserviceVersionRule() {
   public String getAppId() {
     return appId;
   }
+
+  public String getRevision() {
+    return revision;
+  }
+
+  public void setRevision(String revision) {
+    this.revision = revision;
+  }
+
 }
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCacheManagerOld.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCacheManagerOld.java
deleted file mode 100644
index 69d4039ea..000000000
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/cache/InstanceCacheManagerOld.java
+++ /dev/null
@@ -1,204 +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 io.servicecomb.serviceregistry.cache;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.Subscribe;
-
-import io.servicecomb.foundation.common.cache.VersionedCache;
-import io.servicecomb.serviceregistry.ServiceRegistry;
-import io.servicecomb.serviceregistry.api.Const;
-import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
-import io.servicecomb.serviceregistry.api.response.MicroserviceInstanceChangedEvent;
-import io.servicecomb.serviceregistry.config.ServiceRegistryConfig;
-import io.servicecomb.serviceregistry.task.InstancePullTask;
-import io.servicecomb.serviceregistry.task.event.ExceptionEvent;
-import io.servicecomb.serviceregistry.task.event.PeriodicPullEvent;
-import io.servicecomb.serviceregistry.task.event.RecoveryEvent;
-
-/**
- * Created by on 2017/2/21.
- */
-public class InstanceCacheManagerOld implements InstanceCacheManager {
-  private static final Logger LOGGER = LoggerFactory.getLogger(InstanceCacheManagerOld.class);
-
-  private ServiceRegistry serviceRegistry;
-
-  // key?appId/microserviceName
-  protected Map<String, InstanceCache> cacheMap = new ConcurrentHashMap<>();
-
-  private InstancePullTask pullTask;
-
-  // any exception event will set cache not available, but not clear cache
-  // any recovery event will clear cache
-  //
-  // TODO: clear cache is not good, maybe cause no cache data can be used
-  //       it's better to replace the old cache by the new cache, if can't get new cache, then always use old cache.
-  protected boolean cacheAvailable;
-
-  private final Object lockObj = new Object();
-
-  public InstanceCacheManagerOld(EventBus eventBus, ServiceRegistry serviceRegistry,
-      ServiceRegistryConfig serviceRegistryConfig) {
-    this.serviceRegistry = serviceRegistry;
-    pullTask = new InstancePullTask(serviceRegistryConfig.getInstancePullInterval(), this);
-
-    eventBus.register(this);
-  }
-
-  private static String getKey(String appId, String microserviceName) {
-    if (microserviceName.contains(Const.APP_SERVICE_SEPARATOR)) {
-      return microserviceName.replace(Const.APP_SERVICE_SEPARATOR, "/");
-    }
-
-    StringBuilder sb = new StringBuilder(appId.length() + microserviceName.length() + 1);
-    sb.append(appId).append("/").append(microserviceName);
-    return sb.toString();
-  }
-
-  private InstanceCache create(String appId, String microserviceName, String microserviceVersionRule) {
-    InstanceCache instCache = createInstanceCache(appId, microserviceName, microserviceVersionRule);
-    if (instCache == null) {
-      return null;
-    }
-    String key = getKey(appId, microserviceName);
-    cacheMap.put(key, instCache);
-    return instCache;
-  }
-
-  public InstanceCache createInstanceCache(String appId, String microserviceName, String microserviceVersionRule) {
-    List<MicroserviceInstance> instances =
-        serviceRegistry.findServiceInstance(appId, microserviceName, microserviceVersionRule);
-    if (instances == null) {
-      return null;
-    }
-
-    Map<String, MicroserviceInstance> instMap = new HashMap<>();
-    for (MicroserviceInstance instance : instances) {
-      instMap.put(instance.getInstanceId(), instance);
-    }
-
-    InstanceCache instCache = new InstanceCache(appId, microserviceName, microserviceVersionRule, instMap);
-    return instCache;
-  }
-
-  public InstanceCache getOrCreate(String appId, String microserviceName, String microserviceVersionRule) {
-    String key = getKey(appId, microserviceName);
-    InstanceCache cache = cacheMap.get(key);
-    if (cache == null) {
-      synchronized (lockObj) {
-        cache = cacheMap.get(key);
-        if (cache == null) {
-          cache = create(appId, microserviceName, microserviceVersionRule);
-        }
-      }
-    }
-    return cache;
-  }
-
-  @Override
-  public VersionedCache getOrCreateVersionedCache(String appId, String microserviceName,
-      String microserviceVersionRule) {
-    String key = getKey(appId, microserviceName);
-    InstanceCache cache = cacheMap.computeIfAbsent(key, k -> {
-      return createInstanceCache(appId, microserviceName, microserviceVersionRule);
-    });
-    return cache.getVersionedCache();
-  }
-
-  @Subscribe
-  public void onInstanceUpdate(MicroserviceInstanceChangedEvent changedEvent) {
-    String appId = changedEvent.getKey().getAppId();
-    String microserviceName = changedEvent.getKey().getServiceName();
-    String version = changedEvent.getKey().getVersion();
-    String key = getKey(appId, microserviceName);
-
-    synchronized (lockObj) {
-      InstanceCache instCache = cacheMap.get(key);
-      if (instCache == null) {
-        // ??1??????SC???????
-        // ??2???????????????
-        // ???lb???????????
-        return;
-      }
-      Map<String, MicroserviceInstance> instMap = instCache.getInstanceMap();
-
-      switch (changedEvent.getAction()) {
-        case CREATE:
-        case UPDATE:
-          instMap.put(changedEvent.getInstance().getInstanceId(), changedEvent.getInstance());
-          cacheMap.put(key, new InstanceCache(appId, microserviceName, version, instMap));
-          break;
-        case EXPIRE:
-          cacheMap.remove(key);
-          break;
-        case DELETE:
-          instMap.remove(changedEvent.getInstance().getInstanceId());
-          cacheMap.put(key, new InstanceCache(appId, microserviceName, version, instMap));
-          break;
-        default:
-          return;
-      }
-    }
-  }
-
-  public void cleanUp() {
-    synchronized (lockObj) {
-      cacheMap.clear();
-    }
-  }
-
-  public Collection<InstanceCache> getCachedEntries() {
-    return cacheMap.values();
-  }
-
-  public void updateInstanceMap(String appId, String microserviceName, InstanceCache cache) {
-    String key = getKey(appId, microserviceName);
-    cacheMap.put(key, cache);
-  }
-
-  @Subscribe
-  public void onException(ExceptionEvent event) {
-    cacheAvailable = false;
-  }
-
-  @Subscribe
-  public void onRecovered(RecoveryEvent event) {
-    if (!cacheAvailable) {
-      cacheAvailable = true;
-
-      cleanUp();
-      LOGGER.info(
-          "Reconnected to service center, clean up the provider's microservice instances cache.");
-    }
-  }
-
-  @Subscribe
-  public void periodicPull(PeriodicPullEvent event) {
-    pullTask.run();
-  }
-}
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
index 0691af14d..4415b9315 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
@@ -40,6 +40,8 @@
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.api.response.HeartbeatResponse;
 import io.servicecomb.serviceregistry.api.response.MicroserviceInstanceChangedEvent;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
+import io.servicecomb.serviceregistry.definition.DefinitionConst;
 import io.servicecomb.serviceregistry.version.Version;
 import io.servicecomb.serviceregistry.version.VersionRule;
 import io.servicecomb.serviceregistry.version.VersionRuleUtils;
@@ -238,14 +240,17 @@ protected Microservice findLatest(String appId, String serviceName, VersionRule
   }
 
   @Override
-  public List<MicroserviceInstance> findServiceInstance(String selfMicroserviceId, String appId, String serviceName,
-      String strVersionRule) {
+  public MicroserviceInstanceRefresh findServiceInstance(String selfMicroserviceId, String appId, String serviceName,
+      String strVersionRule, String revision) {
     List<MicroserviceInstance> allInstances = new ArrayList<>();
+    MicroserviceInstanceRefresh microserviceInstanceRefresh = new MicroserviceInstanceRefresh();
 
     VersionRule versionRule = VersionRuleUtils.getOrCreate(strVersionRule);
     Microservice latestMicroservice = findLatest(appId, serviceName, versionRule);
     if (latestMicroservice == null) {
-      return allInstances;
+      microserviceInstanceRefresh.setInstances(allInstances);
+      microserviceInstanceRefresh.setRevision(DefinitionConst.DEFAULT_REVISION);
+      return microserviceInstanceRefresh;
     }
 
     Version latestVersion = VersionUtils.getOrCreate(latestMicroservice.getVersion());
@@ -264,7 +269,9 @@ protected Microservice findLatest(String appId, String serviceName, VersionRule
       allInstances.addAll(instances.values());
     }
 
-    return allInstances;
+    microserviceInstanceRefresh.setInstances(allInstances);
+    microserviceInstanceRefresh.setRevision(DefinitionConst.DEFAULT_REVISION);
+    return microserviceInstanceRefresh;
   }
 
   @Override
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/ServiceRegistryClient.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/ServiceRegistryClient.java
index 1c9b750b8..29eac0ccd 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/ServiceRegistryClient.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/ServiceRegistryClient.java
@@ -25,6 +25,7 @@
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.api.response.HeartbeatResponse;
 import io.servicecomb.serviceregistry.api.response.MicroserviceInstanceChangedEvent;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 
 public interface ServiceRegistryClient {
   void init();
@@ -120,10 +121,10 @@ void watch(String selfMicroserviceId, AsyncResultCallback<MicroserviceInstanceCh
 
   /**
    *
-   * ??app+interface+version????endpoints??
+   * ??app+interface+version+revision????endpoints??
    */
-  List<MicroserviceInstance> findServiceInstance(String consumerId, String appId, String serviceName,
-      String versionRule);
+  MicroserviceInstanceRefresh findServiceInstance(String consumerId, String appId, String serviceName,
+      String versionRule, String revision);
   
   /**
    * ??serviceId? instanceId ??instance???
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/MicroserviceInstanceRefresh.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/MicroserviceInstanceRefresh.java
new file mode 100644
index 000000000..37daa10ba
--- /dev/null
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/MicroserviceInstanceRefresh.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd
+ *
+ * Licensed 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 io.servicecomb.serviceregistry.client.http;
+
+import java.util.List;
+
+import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+
+/**
+ * Created by on 2017/12/16.
+ */
+public class MicroserviceInstanceRefresh {
+  private boolean needRefresh = true;
+
+  private String revision;
+
+  private List<MicroserviceInstance> instances;
+
+  public boolean isNeedRefresh() {
+    return needRefresh;
+  }
+
+  public void setNeedRefresh(boolean needRefresh) {
+    this.needRefresh = needRefresh;
+  }
+
+  public String getRevision() {
+    return revision;
+  }
+
+  public void setRevision(String revision) {
+    this.revision = revision;
+  }
+
+  public List<MicroserviceInstance> getInstances() {
+    return instances;
+  }
+
+  public void setInstances(List<MicroserviceInstance> instances) {
+    this.instances = instances;
+  }
+}
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
index 53ffe5c10..a50d5ff27 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
@@ -111,7 +111,7 @@ private void retry(RequestContext requestContext, Handler<RestResponse> response
               holder.value =
                   JsonUtils.readValue(bodyBuffer.getBytes(), cls);
             } catch (Exception e) {
-              LOGGER.warn(bodyBuffer.toString());
+              LOGGER.warn(bodyBuffer.toString(), e);
             }
             countDownLatch.countDown();
           });
@@ -516,10 +516,11 @@ public void watch(String selfMicroserviceId, AsyncResultCallback<MicroserviceIns
   }
 
   @Override
-  public List<MicroserviceInstance> findServiceInstance(String consumerId, String appId, String serviceName,
-      String versionRule) {
+  public MicroserviceInstanceRefresh findServiceInstance(String consumerId, String appId, String serviceName,
+      String versionRule, String revision) {
     Holder<FindInstancesResponse> holder = new Holder<>();
     IpPort ipPort = ipPortManager.getAvailableAddress(false);
+    MicroserviceInstanceRefresh microserviceInstanceRefresh = new MicroserviceInstanceRefresh();
 
     CountDownLatch countDownLatch = new CountDownLatch(1);
     RestUtils.get(ipPort,
@@ -527,18 +528,44 @@ public void watch(String selfMicroserviceId, AsyncResultCallback<MicroserviceIns
         new RequestParam().addQueryParam("appId", appId)
             .addQueryParam("serviceName", serviceName)
             .addQueryParam("version", versionRule)
+            .addQueryParam("rev", revision)
             .addHeader("X-ConsumerId", consumerId),
-        syncHandler(countDownLatch, FindInstancesResponse.class, holder));
+        new Handler<RestResponse>() {
+          @Override
+          public void handle(RestResponse restResponse) {
+            HttpClientResponse response = restResponse.getResponse();
+            response.bodyHandler(
+              bodyBuffer -> {
+                try {
+                  microserviceInstanceRefresh.setRevision(response.getHeader("X-Resource-Revision"));
+                  if (304 == response.statusCode()) {
+                    microserviceInstanceRefresh.setNeedRefresh(false);
+                  } else {
+                    holder.value =
+                        JsonUtils.readValue(bodyBuffer.getBytes(), FindInstancesResponse.class);
+                  }
+                } catch (Exception e) {
+                  LOGGER.warn(bodyBuffer.toString(), e);
+                }
+                countDownLatch.countDown();
+              });
+          }
+        });
     try {
       countDownLatch.await();
+      if (!microserviceInstanceRefresh.isNeedRefresh()) {
+        return microserviceInstanceRefresh;
+      }
       if (holder.value == null) {
         return null; // error
       }
       List<MicroserviceInstance> list = holder.value.getInstances();
       if (list == null) {
-        return new ArrayList<>();
+        microserviceInstanceRefresh.setInstances(new ArrayList<>());
+        return microserviceInstanceRefresh;
       }
-      return list;
+      microserviceInstanceRefresh.setInstances(holder.value.getInstances());
+      return microserviceInstanceRefresh;
     } catch (Exception e) {
       LOGGER.error("find microservice instance {}/{}/{} failed",
           appId,
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/consumer/MicroserviceVersions.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/consumer/MicroserviceVersions.java
index 48bcfaa31..53643e635 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/consumer/MicroserviceVersions.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/consumer/MicroserviceVersions.java
@@ -33,6 +33,7 @@
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstanceStatus;
 import io.servicecomb.serviceregistry.api.response.MicroserviceInstanceChangedEvent;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.definition.DefinitionConst;
 import io.servicecomb.serviceregistry.task.event.PullMicroserviceVersionsInstancesEvent;
 
@@ -47,6 +48,8 @@
 
   private List<MicroserviceInstance> instances;
 
+  private String revision = DefinitionConst.DEFAULT_REVISION;
+
   // key is service id
   private Map<String, MicroserviceVersion> versions = new ConcurrentHashMap<>();
 
@@ -90,6 +93,14 @@ public String getMicroserviceName() {
     return (T) versions.get(serviceId);
   }
 
+  public String getRevision() {
+    return revision;
+  }
+
+  public void setRevision(String revision) {
+    this.revision = revision;
+  }
+
   public void submitPull() {
     pendingPullCount.incrementAndGet();
     pullInstances();
@@ -100,17 +111,27 @@ public void pullInstances() {
       return;
     }
 
-    List<MicroserviceInstance> pulledInstances = RegistryUtils.findServiceInstance(appId,
+    MicroserviceInstanceRefresh microserviceInstanceRefresh = RegistryUtils.findServiceInstance(appId,
         microserviceName,
-        DefinitionConst.VERSION_RULE_ALL);
-    if (pulledInstances == null) {
+        DefinitionConst.VERSION_RULE_ALL,
+        revision);
+    if (microserviceInstanceRefresh == null) {
       return;
     }
 
-    setInstances(pulledInstances);
+    boolean needRefresh = microserviceInstanceRefresh.isNeedRefresh();
+    if (!needRefresh) {
+      return;
+    }
+    String rev = microserviceInstanceRefresh.getRevision();
+    if (Integer.valueOf(revision) - Integer.valueOf(rev) > 0) {
+      return;
+    }
+    List<MicroserviceInstance> pulledInstances = microserviceInstanceRefresh.getInstances();
+    setInstances(pulledInstances, rev);
   }
 
-  private void setInstances(List<MicroserviceInstance> pulledInstances) {
+  private void setInstances(List<MicroserviceInstance> pulledInstances, String rev) {
     synchronized (lock) {
       instances = pulledInstances
           .stream()
@@ -133,6 +154,7 @@ private void setInstances(List<MicroserviceInstance> pulledInstances) {
       for (MicroserviceVersionRule microserviceVersionRule : versionRules.values()) {
         microserviceVersionRule.setInstances(instances);
       }
+      revision = rev;
     }
   }
 
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/definition/DefinitionConst.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/definition/DefinitionConst.java
index a030a3b18..a07e0fd3a 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/definition/DefinitionConst.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/definition/DefinitionConst.java
@@ -31,6 +31,8 @@
 
   String DEFAULT_INSTANCE_ENVIRONMENT = "production";
 
+  String DEFAULT_REVISION = "0";
+
   String VERSION_RULE_LATEST = "latest";
 
   String VERSION_RULE_ALL = "0.0.0+";
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/registry/AbstractServiceRegistry.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/registry/AbstractServiceRegistry.java
index 5e0f98bd8..72a5bffa2 100644
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/registry/AbstractServiceRegistry.java
+++ b/service-registry/src/main/java/io/servicecomb/serviceregistry/registry/AbstractServiceRegistry.java
@@ -38,6 +38,7 @@
 import io.servicecomb.serviceregistry.cache.InstanceCacheManagerOld;
 import io.servicecomb.serviceregistry.client.IpPortManager;
 import io.servicecomb.serviceregistry.client.ServiceRegistryClient;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.config.ServiceRegistryConfig;
 import io.servicecomb.serviceregistry.consumer.AppManager;
 import io.servicecomb.serviceregistry.consumer.MicroserviceVersionFactory;
@@ -208,17 +209,23 @@ public boolean unregisterInstance() {
     return true;
   }
 
-  public List<MicroserviceInstance> findServiceInstance(String appId, String serviceName,
-      String versionRule) {
-    List<MicroserviceInstance> instances = srClient.findServiceInstance(microservice.getServiceId(),
+  public MicroserviceInstanceRefresh findServiceInstance(String appId, String serviceName,
+      String versionRule, String revision) {
+    MicroserviceInstanceRefresh microserviceInstanceRefresh = srClient.findServiceInstance(microservice.getServiceId(),
         appId,
         serviceName,
-        versionRule);
-    if (instances == null) {
+        versionRule,
+        revision);
+    if (microserviceInstanceRefresh == null) {
       LOGGER.error("find empty instances from service center. service={}/{}/{}", appId, serviceName, versionRule);
       return null;
     }
 
+    if (!microserviceInstanceRefresh.isNeedRefresh()) {
+      LOGGER.info("Instances revision is not changed.");
+      return microserviceInstanceRefresh;
+    }
+    List<MicroserviceInstance> instances = microserviceInstanceRefresh.getInstances();
     LOGGER.info("find instances[{}] from service center success. service={}/{}/{}",
         instances.size(),
         appId,
@@ -230,7 +237,7 @@ public boolean unregisterInstance() {
           instance.getInstanceId(),
           instance.getEndpoints());
     }
-    return instances;
+    return microserviceInstanceRefresh;
   }
 
   @Override
diff --git a/service-registry/src/main/java/io/servicecomb/serviceregistry/task/InstancePullTask.java b/service-registry/src/main/java/io/servicecomb/serviceregistry/task/InstancePullTask.java
deleted file mode 100644
index 2fe965d1f..000000000
--- a/service-registry/src/main/java/io/servicecomb/serviceregistry/task/InstancePullTask.java
+++ /dev/null
@@ -1,56 +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 io.servicecomb.serviceregistry.task;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.servicecomb.serviceregistry.cache.InstanceCache;
-import io.servicecomb.serviceregistry.cache.InstanceCacheManagerOld;
-
-public class InstancePullTask implements Runnable {
-  private static final Logger LOGGER = LoggerFactory.getLogger(InstancePullTask.class);
-
-  private ServiceCenterTaskMonitor serviceCenterTaskMonitor = new ServiceCenterTaskMonitor();
-  private InstanceCacheManagerOld cacheManager;
-  private int interval;
-
-  public InstancePullTask(int interval, InstanceCacheManagerOld cacheManager) {
-    this.interval = interval;
-    this.cacheManager = cacheManager;
-  }
-
-  @Override
-  public void run() {
-    try {
-      serviceCenterTaskMonitor.beginCycle(interval);
-      for (InstanceCache cache : this.cacheManager.getCachedEntries()) {
-        InstanceCache newCache = cacheManager.createInstanceCache(cache.getAppId(),
-            cache.getMicroserviceName(),
-            cache.getMicroserviceVersionRule());
-        if (newCache != null) {
-          cacheManager.updateInstanceMap(cache.getAppId(), cache.getMicroserviceName(), newCache);
-        }
-      }
-      serviceCenterTaskMonitor.endCycle();
-    } catch (Throwable e) {
-      // do a protection of long run task.
-      LOGGER.error("unexpected exception in instance pull task.", e);
-    }
-  }
-
-}
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/TestRegistry.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/TestRegistry.java
index dbdc4fdf1..791f46f6e 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/TestRegistry.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/TestRegistry.java
@@ -47,6 +47,7 @@
 import io.servicecomb.foundation.common.net.NetUtils;
 import io.servicecomb.serviceregistry.api.registry.Microservice;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.registry.ServiceRegistryFactory;
 import mockit.Deencapsulation;
 import mockit.Expectations;
@@ -94,7 +95,8 @@ public void testDelegate() {
     Assert.assertEquals(serviceRegistry.getMicroservice(), microservice);
     Assert.assertEquals(serviceRegistry.getMicroserviceInstance(), RegistryUtils.getMicroserviceInstance());
 
-    List<MicroserviceInstance> instanceList = RegistryUtils.findServiceInstance("default", "default", "0.0.1");
+    MicroserviceInstanceRefresh microserviceInstanceRefresh = RegistryUtils.findServiceInstance("default", "default", "0.0.1", "0");
+    List<MicroserviceInstance> instanceList = microserviceInstanceRefresh.getInstances();
     Assert.assertEquals(1, instanceList.size());
     Assert.assertEquals(RegistryUtils.getMicroservice().getServiceId(), instanceList.get(0).getServiceId());
 
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCache.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCache.java
index 8f3393247..fac9594e4 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCache.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCache.java
@@ -46,6 +46,7 @@ public static void beforeClass() {
 
     instMap.put(instance.getInstanceId(), instance);
     instanceCache = new InstanceCache("testAppID", "testMicroServiceName", "1.0", instMap);
+    instanceCache.setRevision("1");
   }
 
   @Test
@@ -54,6 +55,7 @@ public void testGetMethod() {
     Assert.assertEquals("testMicroServiceName", instanceCache.getMicroserviceName());
     Assert.assertEquals("1.0", instanceCache.getMicroserviceVersionRule());
     Assert.assertNotNull(instanceCache.getInstanceMap());
+    Assert.assertEquals("1", instanceCache.getRevision());
   }
 
   @Test
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCacheManagerOld.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCacheManagerOld.java
deleted file mode 100644
index 5b158f09f..000000000
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/cache/TestInstanceCacheManagerOld.java
+++ /dev/null
@@ -1,114 +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 io.servicecomb.serviceregistry.cache;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.google.common.eventbus.EventBus;
-
-import io.servicecomb.foundation.common.cache.VersionedCache;
-import io.servicecomb.serviceregistry.ServiceRegistry;
-import io.servicecomb.serviceregistry.api.MicroserviceKey;
-import io.servicecomb.serviceregistry.api.registry.Microservice;
-import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
-import io.servicecomb.serviceregistry.api.registry.WatchAction;
-import io.servicecomb.serviceregistry.api.response.MicroserviceInstanceChangedEvent;
-import io.servicecomb.serviceregistry.config.ServiceRegistryConfig;
-import io.servicecomb.serviceregistry.registry.ServiceRegistryFactory;
-import io.servicecomb.serviceregistry.task.event.ExceptionEvent;
-import io.servicecomb.serviceregistry.task.event.RecoveryEvent;
-import mockit.Mock;
-import mockit.MockUp;
-import mockit.Mocked;
-
-public class TestInstanceCacheManagerOld {
-
-  @Test
-  public void testInstanceUpdate() {
-    ServiceRegistry serviceRegistry = ServiceRegistryFactory.createLocal();
-    Microservice microservice = serviceRegistry.getMicroservice();
-    serviceRegistry.init();
-    InstanceCacheManagerOld oInstanceCacheManager =
-        (InstanceCacheManagerOld) serviceRegistry.getInstanceCacheManager();
-    Map<String, MicroserviceInstance> instanceMap = new HashMap<>();
-    MicroserviceInstance instance = new MicroserviceInstance();
-    instance.setInstanceId("88887777");
-    instanceMap.put(instance.getInstanceId(), instance);
-    oInstanceCacheManager
-        .updateInstanceMap("default", "default", new InstanceCache("default", "default", "latest", instanceMap));
-
-    MicroserviceInstanceChangedEvent oChangedEvent = new MicroserviceInstanceChangedEvent();
-    oChangedEvent.setAction(WatchAction.UPDATE);
-    MicroserviceKey oKey = new MicroserviceKey();
-    oKey.setAppId(microservice.getAppId());
-    oKey.setVersion(microservice.getVersion());
-    oKey.setServiceName(microservice.getServiceName());
-    oChangedEvent.setKey(oKey);
-    oChangedEvent.setInstance(instance);
-    Assert.assertEquals(1, oInstanceCacheManager.cacheMap.get("default/default").getInstanceMap().size());
-
-    oInstanceCacheManager.onInstanceUpdate(oChangedEvent);
-    oChangedEvent.setAction(WatchAction.DELETE);
-    oInstanceCacheManager.onInstanceUpdate(oChangedEvent);
-    Assert.assertEquals(0, oInstanceCacheManager.cacheMap.get("default/default").getInstanceMap().size());
-
-    oChangedEvent.setAction(WatchAction.CREATE);
-    oInstanceCacheManager.onInstanceUpdate(oChangedEvent);
-    Assert.assertEquals(1, oInstanceCacheManager.cacheMap.get("default/default").getInstanceMap().size());
-    Assert.assertEquals(1, oInstanceCacheManager.getCachedEntries().size());
-
-    Assert.assertEquals("UP", microservice.getInstance().getStatus().toString());
-    oChangedEvent.setAction(WatchAction.EXPIRE);
-    oInstanceCacheManager.onInstanceUpdate(oChangedEvent);
-    Assert.assertEquals(oInstanceCacheManager.cacheMap.size(), 0);
-
-    InstanceCache newServiceCache = oInstanceCacheManager.getOrCreate("default", "newService", "1.0.1");
-    Assert.assertNotNull(newServiceCache);
-    Assert.assertEquals(1, oInstanceCacheManager.getCachedEntries().size());
-
-    oInstanceCacheManager.cacheMap.clear();
-    new MockUp<InstanceCacheManagerOld>(oInstanceCacheManager) {
-      @Mock
-      InstanceCache createInstanceCache(String appId, String microserviceName, String microserviceVersionRule) {
-        return newServiceCache;
-      }
-    };
-    VersionedCache versionedCache = oInstanceCacheManager.getOrCreateVersionedCache("default", "newService", "1.0.1");
-    Assert.assertEquals("1.0.1", versionedCache.name());
-    Assert.assertTrue(versionedCache.isEmpty());
-  }
-
-  @Test
-  public void testCacheAvailable(@Mocked ServiceRegistry serviceRegistry,
-      @Mocked ServiceRegistryConfig serviceRegistryConfig) {
-    EventBus eventBus = new EventBus();
-    InstanceCacheManagerOld instanceCacheManager =
-        new InstanceCacheManagerOld(eventBus, serviceRegistry, serviceRegistryConfig);
-
-    Assert.assertEquals(false, instanceCacheManager.cacheAvailable);
-    eventBus.post(new RecoveryEvent());
-    Assert.assertEquals(true, instanceCacheManager.cacheAvailable);
-
-    eventBus.post(new ExceptionEvent(null));
-    Assert.assertEquals(false, instanceCacheManager.cacheAvailable);
-  }
-}
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImplTest.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImplTest.java
index cde6179d0..a051692a2 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImplTest.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/LocalServiceRegistryClientImplTest.java
@@ -30,6 +30,7 @@
 
 import io.servicecomb.serviceregistry.api.registry.Microservice;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.definition.DefinitionConst;
 
 public class LocalServiceRegistryClientImplTest {
@@ -53,8 +54,9 @@ public void loadRegistryFile() {
   public void testLoadRegistryFile() {
     Assert.assertNotNull(registryClient);
     Assert.assertThat(registryClient.getAllMicroservices().size(), Is.is(1));
-    List<MicroserviceInstance> m =
-        registryClient.findServiceInstance("", "myapp", "springmvctest", DefinitionConst.VERSION_RULE_ALL);
+    MicroserviceInstanceRefresh microserviceInstanceRefresh =
+        registryClient.findServiceInstance("", "myapp", "springmvctest", DefinitionConst.VERSION_RULE_ALL, "0");
+    List<MicroserviceInstance> m = microserviceInstanceRefresh.getInstances();
     Assert.assertEquals(1, m.size());
   }
 
@@ -109,9 +111,9 @@ public void getMicroserviceId_fixVersion() {
 
   @Test
   public void findServiceInstance_noInstances() {
-    List<MicroserviceInstance> result =
-        registryClient.findServiceInstance("self", appId, microserviceName, DefinitionConst.VERSION_RULE_ALL);
-
+    MicroserviceInstanceRefresh microserviceInstanceRefresh =
+        registryClient.findServiceInstance("self", appId, microserviceName, DefinitionConst.VERSION_RULE_ALL, "0");
+    List<MicroserviceInstance> result = microserviceInstanceRefresh.getInstances();
     Assert.assertThat(result, Matchers.empty());
   }
 
@@ -124,9 +126,9 @@ public void findServiceInstance_twoSelectOne() {
     instance.setServiceId(v1.getServiceId());
     registryClient.registerMicroserviceInstance(instance);
 
-    List<MicroserviceInstance> result =
-        registryClient.findServiceInstance("self", appId, microserviceName, "1.0.0");
-
+    MicroserviceInstanceRefresh microserviceInstanceRefresh =
+        registryClient.findServiceInstance("self", appId, microserviceName, "1.0.0", "0");
+    List<MicroserviceInstance> result = microserviceInstanceRefresh.getInstances();
     Assert.assertThat(result, Matchers.contains(instance));
   }
 
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestClientHttp.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestClientHttp.java
index 29f2c989c..6e0547b11 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestClientHttp.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestClientHttp.java
@@ -82,7 +82,8 @@ void open(IpPort ipPort, String url, Handler<Void> onOpen, Handler<Void> onClose
         oClient.findServiceInstance(microservice.getServiceId(),
             microservice.getAppId(),
             microservice.getServiceName(),
-            microservice.getVersion()));
+            microservice.getVersion(),
+            "0"));
     Assert.assertEquals(null,
         oClient.getMicroserviceId(microservice.getAppId(),
             microservice.getServiceName(),
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestMicroserviceInstanceRefresh.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestMicroserviceInstanceRefresh.java
new file mode 100644
index 000000000..044842f59
--- /dev/null
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestMicroserviceInstanceRefresh.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 Huawei Technologies Co., Ltd
+ *
+ * Licensed 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 io.servicecomb.serviceregistry.client.http;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+
+public class TestMicroserviceInstanceRefresh {
+
+  MicroserviceInstanceRefresh microserviceInstanceRefresh = null;
+  List<MicroserviceInstance> instances = null;
+
+  @Before
+  public void setUp() throws Exception {
+    microserviceInstanceRefresh = new MicroserviceInstanceRefresh();
+    instances = new ArrayList<>();
+    instances.add(Mockito.mock(MicroserviceInstance.class));
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    microserviceInstanceRefresh = null;
+    instances = null;
+  }
+
+  @Test
+  public void testDefaultValues() {
+    Assert.assertNull(microserviceInstanceRefresh.getRevision());
+    Assert.assertTrue(microserviceInstanceRefresh.isNeedRefresh());
+    Assert.assertNull(microserviceInstanceRefresh.getInstances());
+  }
+
+  @Test
+  public void testInitializedValues() {
+    initFields(); //Initialize the Object
+    Assert.assertEquals("1", microserviceInstanceRefresh.getRevision());
+    Assert.assertFalse(microserviceInstanceRefresh.isNeedRefresh());
+    Assert.assertEquals(1, microserviceInstanceRefresh.getInstances().size());
+  }
+
+  private void initFields() {
+    microserviceInstanceRefresh.setNeedRefresh(false);
+    microserviceInstanceRefresh.setRevision("1");
+    microserviceInstanceRefresh.setInstances(instances);
+  }
+}
\ No newline at end of file
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
index 364cc031c..4826714d9 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
@@ -124,7 +124,7 @@ public void testException() {
         oClient.unregisterMicroserviceInstance("microserviceId", "microserviceInstanceId"));
     Assert.assertEquals(null, oClient.heartbeat("microserviceId", "microserviceInstanceId"));
     Assert.assertEquals(null,
-        oClient.findServiceInstance("selfMicroserviceId", "appId", "serviceName", "versionRule"));
+        oClient.findServiceInstance("selfMicroserviceId", "appId", "serviceName", "versionRule", "0"));
 
     Assert.assertEquals("a", new ClientException("a").getMessage());
   }
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestAppManager.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestAppManager.java
index 342f329ef..f98bb80f0 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestAppManager.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestAppManager.java
@@ -40,11 +40,13 @@
 
   String versionRule = "0+";
 
+  String revision = "0";
+
   @Test
   public void getOrCreateMicroserviceVersionRule() {
     new Expectations(RegistryUtils.class) {
       {
-        RegistryUtils.findServiceInstance(appId, serviceName, DefinitionConst.VERSION_RULE_ALL);
+        RegistryUtils.findServiceInstance(appId, serviceName, DefinitionConst.VERSION_RULE_ALL, revision);
         result = Collections.emptyList();
       }
     };
@@ -59,7 +61,7 @@ public void getOrCreateMicroserviceVersionRule() {
   public void getOrCreateMicroserviceVersions() {
     new Expectations(RegistryUtils.class) {
       {
-        RegistryUtils.findServiceInstance(appId, serviceName, DefinitionConst.VERSION_RULE_ALL);
+        RegistryUtils.findServiceInstance(appId, serviceName, DefinitionConst.VERSION_RULE_ALL, revision);
         result = Collections.emptyList();
       }
     };
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceManager.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceManager.java
index 2cc9062fb..6629af795 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceManager.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceManager.java
@@ -43,6 +43,8 @@
 
   String versionRule = "0+";
 
+  String revision = "0";
+
   EventBus eventBus = new EventBus();
 
   AppManager appManager = new AppManager(eventBus);
@@ -53,7 +55,7 @@
   public void getOrCreateMicroserviceVersionRule() {
     new Expectations(RegistryUtils.class) {
       {
-        RegistryUtils.findServiceInstance(appId, serviceName, DefinitionConst.VERSION_RULE_ALL);
+        RegistryUtils.findServiceInstance(appId, serviceName, DefinitionConst.VERSION_RULE_ALL, revision);
         result = Collections.emptyList();
       }
     };
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceVersions.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceVersions.java
index eda0f564d..4d89e79b0 100644
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceVersions.java
+++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/consumer/TestMicroserviceVersions.java
@@ -35,6 +35,7 @@
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstanceStatus;
 import io.servicecomb.serviceregistry.api.response.MicroserviceInstanceChangedEvent;
+import io.servicecomb.serviceregistry.client.http.MicroserviceInstanceRefresh;
 import io.servicecomb.serviceregistry.task.event.PullMicroserviceVersionsInstancesEvent;
 import io.servicecomb.serviceregistry.version.Version;
 import mockit.Deencapsulation;
@@ -60,6 +61,8 @@
 
   AtomicInteger pendingPullCount;
 
+  MicroserviceInstanceRefresh microserviceInstanceRefresh = new MicroserviceInstanceRefresh();
+
   public TestMicroserviceVersions() {
     microserviceVersions = new MicroserviceVersions(appManager, appId, microserviceName);
     pendingPullCount = Deencapsulation.getField(microserviceVersions, "pendingPullCount");
@@ -81,15 +84,22 @@ private void createInstance(String microserviceId) {
     instances.add(instance);
   }
 
+  private void createMicroserviceInstanceRefresh() {
+    microserviceInstanceRefresh.setInstances(instances);
+    microserviceInstanceRefresh.setRevision("1");
+    microserviceInstanceRefresh.setNeedRefresh(true);
+  }
+
   private void setup(String microserviceId) {
     createMicroservice(microserviceId);
     createInstance(microserviceId);
+    createMicroserviceInstanceRefresh();
 
     new MockUp<RegistryUtils>() {
       @Mock
-      List<MicroserviceInstance> findServiceInstance(String appId, String serviceName,
-          String versionRule) {
-        return instances;
+      MicroserviceInstanceRefresh findServiceInstance(String appId, String serviceName,
+          String versionRule, String revision) {
+        return microserviceInstanceRefresh;
       }
 
       @Mock
@@ -123,8 +133,8 @@ public void submitPull() {
   public void pullInstancesCancel() {
     new MockUp<RegistryUtils>() {
       @Mock
-      List<MicroserviceInstance> findServiceInstance(String appId, String serviceName,
-          String versionRule) {
+      MicroserviceInstanceRefresh findServiceInstance(String appId, String serviceName,
+          String versionRule, String revision) {
         throw new Error("must not pull");
       }
     };
@@ -139,8 +149,8 @@ public void pullInstancesCancel() {
   public void pullInstancesNull() {
     new MockUp<RegistryUtils>() {
       @Mock
-      List<MicroserviceInstance> findServiceInstance(String appId, String serviceName,
-          String versionRule) {
+      MicroserviceInstanceRefresh findServiceInstance(String appId, String serviceName,
+          String versionRule, String revision) {
         return null;
       }
     };
@@ -169,7 +179,7 @@ public void setInstances_selectUp() {
     setup(microserviceId);
 
     instances.get(0).setStatus(MicroserviceInstanceStatus.DOWN);
-    Deencapsulation.invoke(microserviceVersions, "setInstances", instances);
+    Deencapsulation.invoke(microserviceVersions, "setInstances", instances, "0");
 
     List<?> resultInstances = Deencapsulation.getField(microserviceVersions, "instances");
     Assert.assertTrue(resultInstances.isEmpty());
diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/task/TestInstancePullTask.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/task/TestInstancePullTask.java
deleted file mode 100644
index 3b3df34c4..000000000
--- a/service-registry/src/test/java/io/servicecomb/serviceregistry/task/TestInstancePullTask.java
+++ /dev/null
@@ -1,105 +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 io.servicecomb.serviceregistry.task;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.junit.Test;
-
-import io.servicecomb.serviceregistry.cache.InstanceCache;
-import io.servicecomb.serviceregistry.cache.InstanceCacheManagerOld;
-import mockit.Expectations;
-import mockit.Injectable;
-
-public class TestInstancePullTask {
-  @Test
-  public void testCacheChange(@Injectable InstanceCacheManagerOld cacheManager) {
-    InstancePullTask task = new InstancePullTask(2, cacheManager);
-    InstanceCache serviceCenter = new InstanceCache("sc", "sc", "0.0.1", null);
-    InstanceCache otherService = new InstanceCache("other", "other", "0.0.1", null);
-    Collection<InstanceCache> caches = new ArrayList<>();
-    caches.add(serviceCenter);
-    caches.add(otherService);
-
-    InstanceCache changedServiceCenter = new InstanceCache("sc", "sc", "0.0.1", null);
-    InstanceCache changedService = new InstanceCache("other", "other", "0.0.1", null);
-
-    new Expectations() {
-      {
-        cacheManager.getCachedEntries();
-        result = caches;
-        cacheManager.createInstanceCache("sc", "sc", "0.0.1");
-        result = changedServiceCenter;
-        cacheManager.createInstanceCache("other", "other", "0.0.1");
-        result = changedService;
-        cacheManager.updateInstanceMap("sc", "sc", changedServiceCenter);
-        cacheManager.updateInstanceMap("other", "other", changedService);
-      }
-    };
-
-    task.run();
-    // assertions done in expectations
-  }
-
-  @Test
-  public void testCacheNotChange(@Injectable InstanceCacheManagerOld cacheManager) {
-    InstancePullTask task = new InstancePullTask(2, cacheManager);
-    InstanceCache serviceCenter = new InstanceCache("sc", "sc", "0.0.1", null);
-    InstanceCache otherService = new InstanceCache("other", "other", "0.0.1", null);
-    Collection<InstanceCache> caches = new ArrayList<>();
-    caches.add(serviceCenter);
-    caches.add(otherService);
-
-    new Expectations() {
-      {
-        cacheManager.getCachedEntries();
-        result = caches;
-        cacheManager.createInstanceCache("sc", "sc", "0.0.1");
-        result = serviceCenter;
-        cacheManager.createInstanceCache("other", "other", "0.0.1");
-        result = otherService;
-      }
-    };
-
-    task.run();
-    // assertions done in expectations
-  }
-
-
-  @Test
-  public void testUnexpectedException(@Injectable InstanceCacheManagerOld cacheManager) {
-    InstancePullTask task = new InstancePullTask(2, cacheManager);
-    InstanceCache serviceCenter = new InstanceCache("sc", "sc", "0.0.1", null);
-    InstanceCache otherService = new InstanceCache("other", "other", "0.0.1", null);
-    Collection<InstanceCache> caches = new ArrayList<>();
-    caches.add(serviceCenter);
-    caches.add(otherService);
-
-    new Expectations() {
-      {
-        cacheManager.getCachedEntries();
-        result = caches;
-        cacheManager.createInstanceCache("sc", "sc", "0.0.1");
-        result = new java.lang.Error();
-      }
-    };
-
-    task.run();
-    // will not throw exception in this case
-  }
-}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services