You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/08/25 02:38:35 UTC

[GitHub] liubao68 closed pull request #883: [SBC-870]refactor to using custom RuleExt, not using Robin IRule.

liubao68 closed pull request #883: [SBC-870]refactor to using custom RuleExt, not using Robin IRule.
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/883
 
 
   

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/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
index f94ec2c15..327175b22 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
@@ -65,6 +65,8 @@ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fie
     disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
     enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
     enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
+    // If required=true, need to fail, while required=false, default values is given.
+    enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
 
     SimpleModule module = new SimpleModule();
     // custom types
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
index 38ae6e963..2481e5299 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
@@ -110,7 +110,7 @@ private void testFileAndStringUpload(RestTemplate template, String cseUrlPrefix,
   private void test404(RestTemplate template) {
     HttpClientErrorException exception = null;
     try {
-      template.getForEntity("http://127.0.0.1:8080/aPathNotExist", String.class);
+      template.getForEntity("http://127.0.0.1:8086/aPathNotExist", String.class);
     } catch (RestClientException e) {
       if (e instanceof HttpClientErrorException) {
         exception = (HttpClientErrorException) e;
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java
index cb0eef6e1..c015165be 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java
@@ -18,6 +18,8 @@
 
 import org.apache.servicecomb.loadbalance.Configuration;
 import org.apache.servicecomb.loadbalance.ExtensionsFactory;
+import org.apache.servicecomb.loadbalance.RoundRobinRuleExt;
+import org.apache.servicecomb.loadbalance.RuleExt;
 import org.springframework.stereotype.Component;
 
 import com.netflix.client.DefaultLoadBalancerRetryHandler;
@@ -29,7 +31,7 @@
 @Component
 public class CustomLoadbalanceExtensionsFactory implements ExtensionsFactory {
 
-  class MyCustomRule extends RoundRobinRule {
+  class MyCustomRule extends RoundRobinRuleExt {
 
   }
 
@@ -56,7 +58,7 @@ public boolean isSupport(String key, String value) {
   }
 
   @Override
-  public IRule createLoadBalancerRule(String ruleName) {
+  public RuleExt createLoadBalancerRule(String ruleName) {
     return new MyCustomRule();
   }
 
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
index 89f324c36..c4bbcdd5b 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
@@ -24,9 +24,9 @@ servicecomb:
     registry:
       address: http://127.0.0.1:30100
   rest:
-    address: 0.0.0.0:8080
+    address: 0.0.0.0:8086
   highway:
-    address: 0.0.0.0:7070
+    address: 0.0.0.0:7076
   handler:
     chain:
       Provider:
diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
index 3b55ebb17..ccb01ca79 100644
--- a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
+++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
@@ -111,24 +111,11 @@ public static void run() throws Exception {
       testNull(testFromXml);
       testNull(test);
       testEmpty(test);
+
       // This test case shows destroy of WeightedResponseTimeRule timer task. after test finished will not print:
       // "Weight adjusting job started" and thread "NFLoadBalancer-serverWeightTimer-unknown" destroyed.
       ArchaiusUtils.setProperty("servicecomb.loadbalance.strategy.name", "WeightedResponse");
       testStringArray(test);
-      boolean checkerStated = false;
-      // Timer may not start thread very fast so check for 3 times.
-      for (int i = 0; i < 3; i++) {
-        Set<Thread> allThreads = Thread.getAllStackTraces().keySet();
-        for (Thread t : allThreads) {
-          if (t.getName().equals("NFLoadBalancer-serverWeightTimer-unknown")) {
-            checkerStated = true;
-            break;
-          }
-        }
-        Thread.sleep(1000);
-      }
-      TestMgr.check(checkerStated, true);
-
       ArchaiusUtils.setProperty("servicecomb.loadbalance.strategy.name", "RoundRobin");
       testStringArray(test);
 
diff --git a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
index e70518320..77e95025b 100644
--- a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
+++ b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
@@ -24,9 +24,9 @@ servicecomb:
     registry:
       address: http://127.0.0.1:30100
   rest:
-    address: 0.0.0.0:8080?protocol=http2
+    address: 0.0.0.0:8086?protocol=http2
   highway:
-    address: 0.0.0.0:7070
+    address: 0.0.0.0:7076
   #executors:
     #default: test
     #Provider:
diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
index 09c50e3fe..89e129784 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
@@ -25,9 +25,9 @@ servicecomb:
     registry:
       address: http://127.0.0.1:30100
   rest:
-    address: 0.0.0.0:8080
+    address: 0.0.0.0:8086
   highway:
-    address: 0.0.0.0:7070
+    address: 0.0.0.0:7076
   handler:
     chain:
       Provider:
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index 3e5aa1c15..2a41e0afe 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -167,6 +167,18 @@ public static void run() {
   private static void testController(RestTemplate template, String microserviceName) {
     String prefix = "cse://" + microserviceName;
 
+    TestMgr.check(7,
+        template.getForObject(prefix + "/controller/add?a=3&b=4",
+            Integer.class));
+
+    try {
+      template.getForObject(prefix + "/controller/add",
+          Integer.class);
+      TestMgr.check("failed", "success");
+    } catch (InvocationException e) {
+      TestMgr.check(e.getStatusCode(), 400);
+    }
+
     TestMgr.check("hi world [world]",
         template.getForObject(prefix + "/controller/sayhi?name=world",
             String.class));
diff --git a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
index 2290b6ffe..03b137c79 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
@@ -56,7 +56,8 @@ servicecomb:
     enabled: true
     samplingRate: 0.5
   loadbalance:
-    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
+    strategy:
+      name: WeightedResponse
     retryEnabled: true
     retryOnSame: 1
     retryOnNext: 1
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
index f2f8f624d..2268855f6 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
@@ -35,8 +35,6 @@
 
   public static final String RPOP_TIMER_INTERVAL_IN_MINIS = "servicecomb.loadbalance.stats.timerIntervalInMilis";
 
-  public static final String PROP_POLICY = "NFLoadBalancerRuleClassName";
-
   public static final String PROP_RULE_STRATEGY_NAME = "strategy.name";
 
   // 2.0 configuration items
@@ -91,14 +89,6 @@
   private Configuration() {
   }
 
-  public String getPolicy(String microservice) {
-    return getStringProperty(null,
-        PROP_ROOT + microservice + "." + PROP_POLICY,
-        PROP_ROOT_20 + microservice + "." + PROP_POLICY,
-        PROP_ROOT + PROP_POLICY,
-        PROP_ROOT_20 + PROP_POLICY);
-  }
-
   public String getRuleStrategyName(String microservice) {
     return getStringProperty(null,
         PROP_ROOT + microservice + "." + PROP_RULE_STRATEGY_NAME,
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java
index fa9737274..9077575ee 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java
@@ -25,7 +25,7 @@
 public interface ExtensionsFactory {
   boolean isSupport(String key, String value);
 
-  default IRule createLoadBalancerRule(String ruleName) {
+  default RuleExt createLoadBalancerRule(String ruleName) {
     return null;
   }
 
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java
index 15edefe3d..2df039560 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java
@@ -23,8 +23,6 @@
 import org.slf4j.LoggerFactory;
 
 import com.netflix.client.RetryHandler;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.RoundRobinRule;
 
 public class ExtensionsManager {
   private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionsManager.class);
@@ -35,15 +33,11 @@ public static void addExtentionsFactory(ExtensionsFactory factory) {
     extentionFactories.add(factory);
   }
 
-  public static IRule createLoadBalancerRule(String microservice) {
-    IRule rule = null;
+  public static RuleExt createLoadBalancerRule(String microservice) {
+    RuleExt rule = null;
 
     for (ExtensionsFactory factory : extentionFactories) {
-      if (factory.isSupport(Configuration.PROP_POLICY, Configuration.INSTANCE.getPolicy(microservice))) {
-        rule = factory.createLoadBalancerRule(
-            Configuration.INSTANCE.getPolicy(microservice));
-        break;
-      } else if (factory.isSupport(Configuration.PROP_RULE_STRATEGY_NAME,
+      if (factory.isSupport(Configuration.PROP_RULE_STRATEGY_NAME,
           Configuration.INSTANCE.getRuleStrategyName(microservice))) {
         rule = factory.createLoadBalancerRule(
             Configuration.INSTANCE.getRuleStrategyName(microservice));
@@ -52,7 +46,7 @@ public static IRule createLoadBalancerRule(String microservice) {
     }
 
     if (rule == null) {
-      rule = new RoundRobinRule();
+      rule = new RoundRobinRuleExt();
     }
 
     LOGGER.info("Using load balance rule {} for microservice {}.", rule.getClass().getName(), microservice);
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
index 56db6ff3a..3a96b59c7 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
@@ -17,83 +17,45 @@
 
 package org.apache.servicecomb.loadbalance;
 
-import java.util.Collections;
 import java.util.List;
 
-import com.netflix.loadbalancer.AbstractLoadBalancer;
-import com.netflix.loadbalancer.IRule;
+import org.apache.servicecomb.core.Invocation;
+
 import com.netflix.loadbalancer.LoadBalancerStats;
-import com.netflix.loadbalancer.Server;
 
 /**
- *  Robbin LoadBalancer implementation. Only support IRule and basic operations.
+ *  A load balancer with RuleExt and ServerListFilterExt
  */
-public class LoadBalancer extends AbstractLoadBalancer {
-  private List<Server> serverList = Collections.emptyList();
-
-  private IRule rule;
+public class LoadBalancer {
+  private RuleExt rule;
 
   private LoadBalancerStats lbStats;
 
   private String microServiceName;
 
-  public LoadBalancer(IRule rule, String microServiceName,
-      LoadBalancerStats stats) {
+  private List<ServerListFilterExt> filters;
+
+  private List<ServiceCombServer> servers;
+
+  public LoadBalancer(RuleExt rule, String microServiceName,
+      LoadBalancerStats stats, List<ServerListFilterExt> filters, List<ServiceCombServer> servers) {
     this.microServiceName = microServiceName;
     this.rule = rule;
     this.lbStats = stats;
-  }
-
-  public void setServerList(List<Server> serverList) {
-    this.serverList = Collections.unmodifiableList(serverList);
-  }
-
-  @Override
-  public void addServers(List<Server> newServers) {
-    throw new UnsupportedOperationException("Not implemented.");
-  }
-
-  @Override
-  public Server chooseServer(Object key) {
-    // rule is shared across loadbalancers, so it will get concurrent access problems that it's owned loadbalancer is
-    // not 'this', but this is fine to use other loadbalancer instances only when serverList is correctly set
+    this.filters = filters;
+    this.servers = servers;
     this.rule.setLoadBalancer(this);
-    return rule.choose(key);
-  }
-
-  @Override
-  public void markServerDown(Server server) {
-    throw new UnsupportedOperationException("Not implemented.");
-  }
-
-  @Override
-  @Deprecated
-  public List<Server> getServerList(boolean availableOnly) {
-    return getAllServers();
-  }
-
-  @Override
-  public List<Server> getReachableServers() {
-    return getAllServers();
-  }
-
-  @Override
-  // Different types of Robin Component Rule have different usages for server status and list.
-  // e.g. RoundRobinRule using getAllServers & alive & readyToServe
-  // RandomRule using getReachableServers & alive
-  // WeightedResponseTimeRule using getAllServers & alive
-  // To make all rules work only on "how to choose a server from alive servers", we do not rely on Robbin getReachableServers.
-  // We ensure getReachableServers & getAllServers work in the same way.
-  public List<Server> getAllServers() {
-    return serverList;
+    this.filters.forEach((item) -> item.setLoadBalancer(this));
   }
 
-  @Override
-  public List<Server> getServerList(ServerGroup serverGroup) {
-    throw new UnsupportedOperationException("Not implemented.");
+  public ServiceCombServer chooseServer(Invocation invocation) {
+    List<ServiceCombServer> temp = this.servers;
+    for (ServerListFilterExt filterExt : filters) {
+      temp = filterExt.getFilteredListOfServers(temp, invocation);
+    }
+    return rule.choose(temp, invocation);
   }
 
-  @Override
   public LoadBalancerStats getLoadBalancerStats() {
     return lbStats;
   }
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
index eedbb9ce3..5cb18dcd7 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
@@ -17,19 +17,12 @@
 
 package org.apache.servicecomb.loadbalance;
 
-import java.util.Collections;
 import java.util.List;
 
-import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.netflix.loadbalancer.IRule;
 import com.netflix.loadbalancer.LoadBalancerStats;
-import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
 
 /**
  *  Create a suitable load balancer for each invocation.
@@ -45,11 +38,7 @@
  *  on the result of ServerListFilter, they should not contain operation level state information in instance fields.
  */
 public class LoadBalancerCreator {
-  private static final Logger LOGGER = LoggerFactory.getLogger(LoadBalancerCreator.class);
-
-  private List<Server> serverList = Collections.emptyList();
-
-  private IRule rule;
+  private RuleExt rule;
 
   private LoadBalancerStats lbStats;
 
@@ -57,7 +46,7 @@
 
   private String microServiceName;
 
-  public LoadBalancerCreator(IRule rule, String microServiceName) {
+  public LoadBalancerCreator(RuleExt rule, String microServiceName) {
     this.rule = rule;
     this.microServiceName = microServiceName;
     this.lbStats = new LoadBalancerStats(null);
@@ -66,20 +55,7 @@ public LoadBalancerCreator(IRule rule, String microServiceName) {
   }
 
   public void shutdown() {
-    // netflix components does not have a proper way to shutdown laodbalancers so we do it in a not quite elegant way.
-    if (this.rule instanceof WeightedResponseTimeRule) {
-      ((WeightedResponseTimeRule) this.rule).shutdown();
-    }
-  }
-
-  // every filter group has a loadBalancer instance
-  // serverList almost not changed for different invocation
-  // so every invocation will call setServerList, this is no problem
-  public void setServerList(List<Server> serverList) {
-    if (serverList.isEmpty()) {
-      LOGGER.warn("Set empty server list.");
-    }
-    this.serverList = Collections.unmodifiableList(serverList);
+    // nothing to do now
   }
 
   @VisibleForTesting
@@ -87,17 +63,7 @@ void setFilters(List<ServerListFilterExt> filters) {
     this.filters = filters;
   }
 
-  public LoadBalancer createLoadBalancer(Invocation invocation) {
-    LoadBalancer loadBalancer = new LoadBalancer(rule, microServiceName, lbStats);
-    List<Server> servers = this.serverList;
-    for (ServerListFilterExt filter : this.filters) {
-      filter.setLoadBalancer(loadBalancer);
-      servers = filter.getFilteredListOfServers(servers, invocation);
-      if (servers.isEmpty()) {
-        LOGGER.warn("Filter {} get empty list.", filter.getClass().getName());
-      }
-    }
-    loadBalancer.setServerList(servers);
-    return loadBalancer;
+  public LoadBalancer createLoadBalancer(List<ServiceCombServer> servers) {
+    return new LoadBalancer(rule, microServiceName, lbStats, filters, servers);
   }
 }
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
index 7d6394a46..06f4b1042 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
@@ -45,7 +45,6 @@
 import org.slf4j.LoggerFactory;
 
 import com.netflix.loadbalancer.ILoadBalancer;
-import com.netflix.loadbalancer.IRule;
 import com.netflix.loadbalancer.Server;
 import com.netflix.loadbalancer.reactive.ExecutionContext;
 import com.netflix.loadbalancer.reactive.ExecutionInfo;
@@ -56,8 +55,7 @@
 import rx.Observable;
 
 /**
- * 负载均衡处理链
- *
+ *  Load balance handler.
  */
 public class LoadbalanceHandler implements Handler {
   // just a wrapper to make sure in retry mode to choose a different server.
@@ -67,21 +65,23 @@
 
     Server lastServer = null;
 
-    ILoadBalancer delegate;
+    LoadBalancer delegate;
+
+    Invocation invocation;
 
-    RetryLoadBalancer(ILoadBalancer delegate) {
+    RetryLoadBalancer(LoadBalancer delegate, Invocation invocation) {
       this.delegate = delegate;
     }
 
     @Override
     public void addServers(List<Server> newServers) {
-      delegate.addServers(newServers);
+      throw new UnsupportedOperationException("Not implemented.");
     }
 
     @Override
     public Server chooseServer(Object key) {
       for (int i = 0; i < COUNT; i++) {
-        Server s = delegate.chooseServer(key);
+        Server s = delegate.chooseServer(invocation);
         if (s != null && !s.equals(lastServer)) {
           lastServer = s;
           break;
@@ -94,23 +94,23 @@ public Server chooseServer(Object key) {
 
     @Override
     public void markServerDown(Server server) {
-      delegate.markServerDown(server);
+      throw new UnsupportedOperationException("Not implemented.");
     }
 
     @Override
     @Deprecated
     public List<Server> getServerList(boolean availableOnly) {
-      return delegate.getServerList(availableOnly);
+      throw new UnsupportedOperationException("Not implemented.");
     }
 
     @Override
     public List<Server> getReachableServers() {
-      return delegate.getReachableServers();
+      throw new UnsupportedOperationException("Not implemented.");
     }
 
     @Override
     public List<Server> getAllServers() {
-      return delegate.getAllServers();
+      throw new UnsupportedOperationException("Not implemented.");
     }
   }
 
@@ -135,8 +135,6 @@ public Thread newThread(Runnable r) {
 
   private final Object lock = new Object();
 
-  private String policy = null;
-
   private String strategy = null;
 
 
@@ -148,16 +146,13 @@ public LoadbalanceHandler() {
 
   @Override
   public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
-    String policy = Configuration.INSTANCE.getPolicy(invocation.getMicroserviceName());
     String strategy = Configuration.INSTANCE.getRuleStrategyName(invocation.getMicroserviceName());
-    boolean isRuleNotChanged = isEqual(policy, this.policy) && isEqual(strategy, this.strategy);
-    if (!isRuleNotChanged) {
+    if (!isEqual(strategy, this.strategy)) {
       //配置变化,需要重新生成所有的lb实例
       synchronized (lock) {
         clearLoadBalancer();
       }
     }
-    this.policy = policy;
     this.strategy = strategy;
     LoadBalancer loadBalancer = getOrCreateLoadBalancer(invocation);
 
@@ -199,10 +194,10 @@ private void send(Invocation invocation, AsyncResponse asyncResp, final LoadBala
       chosenLB.getLoadBalancerStats().noteResponseTime(server, (System.currentTimeMillis() - time));
       if (isFailedResponse(resp)) {
         chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(server);
-        ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
+        ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, System.currentTimeMillis() - time);
       } else {
         chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(server);
-        ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+        ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, (System.currentTimeMillis() - time));
       }
       asyncResp.handle(resp);
     });
@@ -287,7 +282,7 @@ public void onExecutionFailed(ExecutionContext<Invocation> context, Throwable fi
     ExecutionContext<Invocation> context = new ExecutionContext<>(invocation, null, null, null);
 
     LoadBalancerCommand<Response> command = LoadBalancerCommand.<Response>builder()
-        .withLoadBalancer(new RetryLoadBalancer(chosenLB))
+        .withLoadBalancer(new RetryLoadBalancer(chosenLB, invocation))
         .withServerLocator(invocation)
         .withRetryHandler(ExtensionsManager.createRetryHandler(invocation.getMicroserviceName()))
         .withListeners(listeners)
@@ -309,13 +304,13 @@ public void onExecutionFailed(ExecutionContext<Invocation> context, Throwable fi
                     ((Throwable) resp.getResult()).getMessage(),
                     s);
                 chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-                ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
+                ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, System.currentTimeMillis() - time);
                 f.onError(resp.getResult());
               } else {
                 chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(s);
                 chosenLB.getLoadBalancerStats().noteResponseTime(s,
                     (System.currentTimeMillis() - time));
-                ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+                ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, (System.currentTimeMillis() - time));
                 f.onNext(resp);
                 f.onCompleted();
               }
@@ -359,15 +354,16 @@ protected LoadBalancer getOrCreateLoadBalancer(Invocation invocation) {
     LoadBalancerCreator loadBalancerCreator = loadBalancerMap.computeIfAbsent(serversVersionedCache.name(), name -> {
       return createLoadBalancerCreator(invocation.getMicroserviceName());
     });
-    loadBalancerCreator.setServerList(serversVersionedCache.data());
-    // help users to deal with incompatible changes.
+
+    // Nothing to do just help users to deal with incompatible changes.
     setTransactionControlFilter(invocation.getMicroserviceName());
     loadServerListFilters();
-    return loadBalancerCreator.createLoadBalancer(invocation);
+
+    return loadBalancerCreator.createLoadBalancer(serversVersionedCache.data());
   }
 
   private LoadBalancerCreator createLoadBalancerCreator(String microserviceName) {
-    IRule rule = ExtensionsManager.createLoadBalancerRule(microserviceName);
+    RuleExt rule = ExtensionsManager.createLoadBalancerRule(microserviceName);
     LoadBalancerCreator creator = new LoadBalancerCreator(rule, microserviceName);
     return creator;
   }
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
new file mode 100644
index 000000000..60eedac52
--- /dev/null
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
@@ -0,0 +1,39 @@
+/*
+ * 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.servicecomb.loadbalance;
+
+import java.util.List;
+import java.util.Random;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * A random rule.
+ */
+public class RandomRuleExt implements RuleExt {
+  private Random random = new Random();
+
+  @Override
+  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
+    if (servers.size() == 0) {
+      return null;
+    }
+    int index = Math.abs(random.nextInt()) % servers.size();
+    return servers.get(index);
+  }
+}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
new file mode 100644
index 000000000..c3a887d20
--- /dev/null
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
@@ -0,0 +1,39 @@
+/*
+ * 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.servicecomb.loadbalance;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * A round robin rule
+ */
+public class RoundRobinRuleExt implements RuleExt {
+  private AtomicInteger counter = new AtomicInteger(0);
+
+  @Override
+  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
+    if (servers.size() == 0) {
+      return null;
+    }
+    int index = Math.abs(counter.getAndIncrement()) % servers.size();
+    return servers.get(index);
+  }
+}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
deleted file mode 100644
index b6df5ef21..000000000
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.servicecomb.loadbalance;
-
-import java.util.Collection;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.servicecomb.foundation.common.utils.JvmUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import com.google.common.collect.Lists;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.RoundRobinRule;
-
-/**
- * 兼容老版本的Rule相关的配置项
- */
-@Component
-public class RuleClassNameExtentionsFactory implements ExtensionsFactory {
-  private static final Logger LOGGER = LoggerFactory.getLogger(RuleClassNameExtentionsFactory.class);
-
-  private static final Collection<String> ACCEPT_KEYS = Lists.newArrayList(
-      Configuration.PROP_POLICY);
-
-  // possible values
-  //      "com.netflix.loadbalancer.RoundRobinRule"
-  //      "com.netflix.loadbalancer.WeightedResponseTimeRule"
-  //      "com.netflix.loadbalancer.RandomRule"
-  //      "org.apache.servicecomb.loadbalance.SessionStickinessRule"
-  @Override
-  public boolean isSupport(String key, String value) {
-    return ACCEPT_KEYS.contains(key) && StringUtils.isNotEmpty(value);
-  }
-
-  @Override
-  public IRule createLoadBalancerRule(String ruleName) {
-    IRule rule;
-    try {
-      rule = (IRule) Class.forName(ruleName, true, JvmUtils.findClassLoader()).newInstance();
-    } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
-      LOGGER.warn("Loadbalance rule [{}] is incorrect, using default RoundRobinRule.", ruleName);
-      rule = new RoundRobinRule();
-    }
-    return rule;
-  }
-}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
new file mode 100644
index 000000000..a95ccbcd2
--- /dev/null
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
@@ -0,0 +1,32 @@
+/*
+ * 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.servicecomb.loadbalance;
+
+import java.util.List;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * Load balance rule to support invocation based filters.
+ */
+public interface RuleExt {
+  default void setLoadBalancer(LoadBalancer loadBalancer) {
+  }
+
+  ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation);
+}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java
index 92d5be235..5ab7cfb95 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java
@@ -21,10 +21,6 @@
 import org.springframework.stereotype.Component;
 
 import com.google.common.collect.Lists;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.RandomRule;
-import com.netflix.loadbalancer.RoundRobinRule;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
 
 @Component
 public class RuleNameExtentionsFactory implements ExtensionsFactory {
@@ -51,13 +47,13 @@ public boolean isSupport(String key, String value) {
   }
 
   @Override
-  public IRule createLoadBalancerRule(String ruleName) {
+  public RuleExt createLoadBalancerRule(String ruleName) {
     if (RULE_RoundRobin.equals(ruleName)) {
-      return new RoundRobinRule();
+      return new RoundRobinRuleExt();
     } else if (RULE_Random.equals(ruleName)) {
-      return new RandomRule();
+      return new RandomRuleExt();
     } else if (RULE_WeightedResponse.equals(ruleName)) {
-      return new WeightedResponseTimeRule();
+      return new WeightedResponseTimeRuleExt();
     } else if (RULE_SessionStickiness.equals(ruleName)) {
       return new SessionStickinessRule();
     } else {
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java
index 7695a6827..9dba0046d 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java
@@ -21,27 +21,23 @@
 
 import org.apache.servicecomb.core.Invocation;
 
-import com.netflix.loadbalancer.Server;
-
 /**
  *  Base interface for server list filters.
  *
- *  LoadBalancer.getAllServers ServerListFilterExt.getFilteredListOfServers IRule.choose
- *
  *  Robin ServerListFilter can not support invocation based filter strategies, so we create a new one to
  *  support this.
  */
 public interface ServerListFilterExt {
-  public default int getOrder() {
+  default int getOrder() {
     return 0;
   }
 
-  public default boolean enabled() {
+  default boolean enabled() {
     return true;
   }
 
-  public default void setLoadBalancer(LoadBalancer loadBalancer) {
+  default void setLoadBalancer(LoadBalancer loadBalancer) {
   }
 
-  public List<Server> getFilteredListOfServers(List<Server> servers, Invocation invocation);
+  List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> servers, Invocation invocation);
 }
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
index 1b7be1d77..ac01152ab 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
@@ -57,6 +57,8 @@
 
   public static final ServiceCombLoadBalancerStats INSTANCE;
 
+  private Timer timer;
+
   static {
     INSTANCE = new ServiceCombLoadBalancerStats();
     INSTANCE.init();
@@ -76,17 +78,17 @@ public void markIsolated(ServiceCombServer server, boolean isolated) {
     }
   }
 
-  public void markSuccess(ServiceCombServer server) {
+  public void markSuccess(ServiceCombServer server, long execTime) {
     try {
-      serverStatsCache.get(server).markSuccess();
+      serverStatsCache.get(server).markSuccess(execTime);
     } catch (ExecutionException e) {
       LOGGER.error("Not expected to happen, maybe a bug.", e);
     }
   }
 
-  public void markFailure(ServiceCombServer server) {
+  public void markFailure(ServiceCombServer server, long execTime) {
     try {
-      serverStatsCache.get(server).markFailure();
+      serverStatsCache.get(server).markFailure(execTime);
     } catch (ExecutionException e) {
       LOGGER.error("Not expected to happen, maybe a bug.", e);
     }
@@ -126,6 +128,14 @@ void setTimerIntervalInMilis(int milis) {
   }
 
   void init() {
+    // for testing
+    if (timer != null) {
+      timer.cancel();
+    }
+    if (serverStatsCache != null) {
+      serverStatsCache.cleanUp();
+    }
+
     serverStatsCache =
         CacheBuilder.newBuilder()
             .expireAfterAccess(serverExpireInSeconds, TimeUnit.SECONDS)
@@ -145,7 +155,7 @@ public ServiceCombServerStats load(ServiceCombServer server) {
                   }
                 });
 
-    Timer timer = new Timer("LoadBalancerStatsTimer", true);
+    timer = new Timer("LoadBalancerStatsTimer", true);
     timer.schedule(new TimerTask() {
       private MicroserviceInstancePing ping = SPIServiceUtils.getPriorityHighestService(MicroserviceInstancePing.class);
 
@@ -157,10 +167,11 @@ public void run() {
           while (instances.hasNext()) {
             ServiceCombServer server = instances.next();
             ServiceCombServerStats stats = allServers.get(server);
+            long startTime = System.currentTimeMillis();
             if ((System.currentTimeMillis() - stats.getLastVisitTime() > timerIntervalInMilis) && !ping
                 .ping(server.getInstance())) {
               LOGGER.info("ping mark server {} failure.", server.getInstance().getInstanceId());
-              stats.markFailure();
+              stats.markFailure(System.currentTimeMillis() - startTime);
             }
           }
           serverStatsCache.cleanUp();
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
index 1d4edf331..800e2aebe 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
@@ -22,6 +22,7 @@
 import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import org.apache.servicecomb.serviceregistry.cache.CacheEndpoint;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.netflix.loadbalancer.Server;
 
 /**
@@ -35,6 +36,21 @@
   // 所属服务实例
   private final MicroserviceInstance instance;
 
+  @VisibleForTesting
+  ServiceCombServer(Endpoint endpoint, MicroserviceInstance instance) {
+    super(null);
+    this.endpoint = endpoint;
+    this.instance = instance;
+
+    // Different types of Robin Component Rule have different usages for server status and list.
+    // e.g. RoundRobinRule using getAllServers & alive & readyToServe
+    // RandomRule using getReachableServers & alive
+    // WeightedResponseTimeRule using getAllServers & alive
+    // To make all rules work only on "how to choose a server from alive servers", we do not rely on Robbin defined status
+    this.setAlive(true);
+    this.setReadyToServe(true);
+  }
+
   public ServiceCombServer(Transport transport, CacheEndpoint cacheEndpoint) {
     super(null);
 
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
index b33771bba..03b458e57 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
@@ -45,33 +45,47 @@
 
   private boolean isolated = false;
 
+  private long averageResponseTime = 0;
+
+  public long getAverageResponseTime() {
+    return averageResponseTime;
+  }
+
   public void markIsolated(boolean isolated) {
     this.isolated = isolated;
   }
 
-  public void markSuccess() {
+  public void markSuccess(long execTime) {
     long time = System.currentTimeMillis();
     ensureWindow(time);
     lastVisitTime = time;
     lastActiveTime = time;
+    updateAvgTime(execTime);
     totalRequests.incrementAndGet();
     successRequests.incrementAndGet();
     continuousFailureCount.set(0);
   }
 
-  public void markFailure() {
+  public void markFailure(long execTime) {
     long time = System.currentTimeMillis();
     ensureWindow(time);
     lastVisitTime = time;
 
     // when isolated, do not update any failure statistics, or we can not recover from failure very quickly
     if (!isolated) {
+      updateAvgTime(execTime);
       totalRequests.incrementAndGet();
       failedRequests.incrementAndGet();
       continuousFailureCount.incrementAndGet();
     }
   }
 
+  private void updateAvgTime(long execTime) {
+    // There maybe concurrent problems. But we do not care.
+    long total = totalRequests.get();
+    averageResponseTime = (averageResponseTime * total + execTime) / (total + 1);
+  }
+
   private void ensureWindow(long time) {
     if (time - lastWindow > TIME_WINDOW_IN_MILLISECONDS) {
       synchronized (lock) {
@@ -81,6 +95,7 @@ private void ensureWindow(long time) {
             totalRequests.set(0);
             successRequests.set(0);
             failedRequests.set(0);
+            averageResponseTime = 0;
           }
           lastWindow = time;
         }
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java
index d589b4d42..a489860ed 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java
@@ -17,15 +17,13 @@
 
 package org.apache.servicecomb.loadbalance;
 
+import java.util.List;
+
+import org.apache.servicecomb.core.Invocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.netflix.loadbalancer.AbstractLoadBalancer;
-import com.netflix.loadbalancer.ILoadBalancer;
-import com.netflix.loadbalancer.IRule;
 import com.netflix.loadbalancer.LoadBalancerStats;
-import com.netflix.loadbalancer.RoundRobinRule;
-import com.netflix.loadbalancer.Server;
 import com.netflix.loadbalancer.ServerStats;
 
 /**
@@ -33,17 +31,17 @@
  * 提供当会话过期或者失败次数超过限制后,轮询选择其他服务器的能力。
  *
  */
-public class SessionStickinessRule implements IRule {
+public class SessionStickinessRule implements RuleExt {
   private static final Logger LOG = LoggerFactory.getLogger(SessionStickinessRule.class);
 
   private final Object lock = new Object();
 
-  private ILoadBalancer lb;
+  private LoadBalancer loadBalancer;
 
   // use random rule as the trigger rule, to prevent consumer instance select the same producer instance.
-  private IRule triggerRule;
+  private RuleExt triggerRule;
 
-  private volatile Server lastServer = null;
+  private volatile ServiceCombServer lastServer = null;
 
   private long lastAccessedTime = 0;
 
@@ -54,39 +52,41 @@
   private String microserviceName;
 
   public SessionStickinessRule() {
-    triggerRule = new RoundRobinRule();
+    triggerRule = new RoundRobinRuleExt();
+  }
+
+  public void setLoadBalancer(LoadBalancer loadBalancer) {
+    this.loadBalancer = loadBalancer;
   }
 
-  private Server chooseNextServer(Object key) {
-    AbstractLoadBalancer lb = (AbstractLoadBalancer) getLoadBalancer();
-    triggerRule.setLoadBalancer(lb);
-    lastServer = triggerRule.choose(key);
+  private ServiceCombServer chooseNextServer(List<ServiceCombServer> servers, Invocation invocation) {
+    lastServer = triggerRule.choose(servers, invocation);
     lastAccessedTime = System.currentTimeMillis();
     return lastServer;
   }
 
-  private Server chooseInitialServer(Object key) {
+  private ServiceCombServer chooseInitialServer(List<ServiceCombServer> servers, Invocation invocation) {
     synchronized (lock) {
       if (lastServer == null) {
-        chooseNextServer(key);
+        chooseNextServer(servers, invocation);
       }
     }
     return lastServer;
   }
 
-  private Server chooseServerWhenTimeout(Object key) {
+  private ServiceCombServer chooseServerWhenTimeout(List<ServiceCombServer> servers, Invocation invocation) {
     synchronized (lock) {
       if (isTimeOut()) {
-        chooseNextServer(key);
+        chooseNextServer(servers, invocation);
       }
     }
     return lastServer;
   }
 
-  private Server chooseServerErrorThresholdMet(Object key) {
+  private ServiceCombServer chooseServerErrorThresholdMet(List<ServiceCombServer> servers, Invocation invocation) {
     synchronized (lock) {
       if (errorThresholdMet) {
-        chooseNextServer(key);
+        chooseNextServer(servers, invocation);
         errorThresholdMet = false;
       }
     }
@@ -101,8 +101,7 @@ private boolean isTimeOut() {
   }
 
   private boolean isErrorThresholdMet() {
-    AbstractLoadBalancer lb = (AbstractLoadBalancer) getLoadBalancer();
-    LoadBalancerStats stats = lb.getLoadBalancerStats();
+    LoadBalancerStats stats = loadBalancer.getLoadBalancerStats();
 
     if (stats != null && stats.getServerStats() != null && stats.getServerStats().size() > 0) {
       ServerStats serverStats = stats.getSingleServerStat(lastServer);
@@ -117,14 +116,14 @@ private boolean isErrorThresholdMet() {
   }
 
   @Override
-  public Server choose(Object key) {
+  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
     if (lastServer == null) {
-      return chooseInitialServer(key);
+      return chooseInitialServer(servers, invocation);
     }
 
     if (isTimeOut()) {
       LOG.warn("session timeout. choose another server.");
-      return chooseServerWhenTimeout(key);
+      return chooseServerWhenTimeout(servers, invocation);
     } else {
       this.lastAccessedTime = System.currentTimeMillis();
     }
@@ -132,28 +131,13 @@ public Server choose(Object key) {
     if (isErrorThresholdMet()) {
       LOG.warn("reached max error. choose another server.");
       errorThresholdMet = true;
-      return chooseServerErrorThresholdMet(key);
+      return chooseServerErrorThresholdMet(servers, invocation);
     }
 
-    if (!isLastServerExists(lastServer)) {
-      return chooseNextServer(key);
+    if (!servers.contains(lastServer)) {
+      return chooseNextServer(servers, invocation);
     }
 
     return lastServer;
   }
-
-  private boolean isLastServerExists(Server lastServer2) {
-    return this.lb.getReachableServers().contains(lastServer2);
-  }
-
-  @Override
-  public void setLoadBalancer(ILoadBalancer lb) {
-    this.lb = lb;
-    this.microserviceName = ((LoadBalancer) lb).getMicroServiceName();
-  }
-
-  @Override
-  public ILoadBalancer getLoadBalancer() {
-    return this.lb;
-  }
 }
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
new file mode 100644
index 000000000..06aba4f57
--- /dev/null
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
@@ -0,0 +1,65 @@
+/*
+ * 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.servicecomb.loadbalance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * Rule based on response time.
+ */
+public class WeightedResponseTimeRuleExt extends RoundRobinRuleExt {
+  // 10ms
+  private static final int MIN_GAP = 10;
+
+  private Random random = new Random();
+
+  @Override
+  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
+    List<AtomicInteger> stats = new ArrayList<>(servers.size());
+    int totalWeights = 0;
+    boolean needRandom = false;
+    for (ServiceCombServer server : servers) {
+      ServiceCombServerStats serverStats = ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(server);
+      int avgTime = (int) serverStats.getAverageResponseTime();
+      if (!needRandom && avgTime > MIN_GAP) {
+        needRandom = true;
+      }
+      totalWeights += avgTime;
+      stats.add(new AtomicInteger(avgTime));
+    }
+
+    if (needRandom) {
+      int finalTotal = totalWeights;
+      stats.forEach(item -> item.set(finalTotal - item.get()));
+      int ran = random
+          .nextInt(Math.max(totalWeights * stats.size() - totalWeights, 1));
+      for (int i = 0; i < stats.size(); i++) {
+        ran -= stats.get(i).get();
+        if (ran < 0) {
+          return servers.get(i);
+        }
+      }
+    }
+    return super.choose(servers, invocation);
+  }
+}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
index ed0878988..6f93b44c7 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
@@ -30,7 +30,7 @@
  */
 public class MyServerListFilterExt implements ServerListFilterExt {
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
+  public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList, Invocation invocation) {
     if (invocation.getAppId().equals("test")) {
       return new ArrayList<>();
     }
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java
index 08d498dd7..6ef2160a8 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java
@@ -35,7 +35,6 @@
   public void testConstants() {
 
     assertEquals("servicecomb.loadbalance.", Configuration.PROP_ROOT);
-    assertEquals("NFLoadBalancerRuleClassName", Configuration.PROP_POLICY);
     assertEquals("ribbon.", Configuration.PROP_ROOT_20);
     assertEquals("retryEnabled", Configuration.PROP_RETRY_ENABLED);
     assertEquals("retryOnNext", Configuration.PROP_RETRY_ONNEXT);
@@ -47,7 +46,6 @@ public void testConstants() {
 
   @Test
   public void testFullConfigurationWithArgsString() {
-    assertNull(Configuration.INSTANCE.getPolicy("test"));
     assertNotNull(Configuration.INSTANCE.getRetryOnNext("test"));
     assertNotNull(Configuration.INSTANCE.getRetryOnSame("test"));
     assertNotNull(Configuration.INSTANCE.isRetryEnabled("test"));
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java
index 69c4a1eca..169e91a79 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java
@@ -60,17 +60,16 @@ public void testRuleName() {
 
     BeansHolder holder = new BeansHolder();
     List<ExtensionsFactory> extensionsFactories = new ArrayList<>();
-    extensionsFactories.add(new RuleClassNameExtentionsFactory());
     extensionsFactories.add(new RuleNameExtentionsFactory());
     extensionsFactories.add(new DefaultRetryExtensionsFactory());
     Deencapsulation.setField(holder, "extentionsFactories", extensionsFactories);
     holder.init();
 
-    Assert.assertEquals(RoundRobinRule.class.getName(),
+    Assert.assertEquals(RoundRobinRuleExt.class.getName(),
         ExtensionsManager.createLoadBalancerRule("mytest1").getClass().getName());
-    Assert.assertEquals(RandomRule.class.getName(),
+    Assert.assertEquals(RandomRuleExt.class.getName(),
         ExtensionsManager.createLoadBalancerRule("mytest2").getClass().getName());
-    Assert.assertEquals(WeightedResponseTimeRule.class.getName(),
+    Assert.assertEquals(WeightedResponseTimeRuleExt.class.getName(),
         ExtensionsManager.createLoadBalancerRule("mytest3").getClass().getName());
     Assert.assertEquals(SessionStickinessRule.class.getName(),
         ExtensionsManager.createLoadBalancerRule("mytest4").getClass().getName());
@@ -84,36 +83,12 @@ public void testRuleName() {
 
   @Test
   public void testRuleClassName() {
-    System.setProperty("servicecomb.loadbalance.mytest1.NFLoadBalancerRuleClassName",
-        "com.netflix.loadbalancer.RoundRobinRule");
-    System.setProperty("servicecomb.loadbalance.mytest2.NFLoadBalancerRuleClassName",
-        "com.netflix.loadbalancer.WeightedResponseTimeRule");
-    System.setProperty("servicecomb.loadbalance.mytest3.NFLoadBalancerRuleClassName", "com.netflix.loadbalancer.RandomRule");
-    System.setProperty("servicecomb.loadbalance.mytest4.NFLoadBalancerRuleClassName",
-        "org.apache.servicecomb.loadbalance.SessionStickinessRule");
-
     BeansHolder holder = new BeansHolder();
     List<ExtensionsFactory> extensionsFactories = new ArrayList<>();
-    extensionsFactories.add(new RuleClassNameExtentionsFactory());
     extensionsFactories.add(new RuleNameExtentionsFactory());
     extensionsFactories.add(new DefaultRetryExtensionsFactory());
     Deencapsulation.setField(holder, "extentionsFactories", extensionsFactories);
     holder.init();
-
-    Assert.assertEquals(RoundRobinRule.class.getName(),
-        ExtensionsManager.createLoadBalancerRule("mytest1").getClass().getName());
-    Assert.assertEquals(WeightedResponseTimeRule.class.getName(),
-        ExtensionsManager.createLoadBalancerRule("mytest2").getClass().getName());
-    Assert.assertEquals(RandomRule.class.getName(),
-        ExtensionsManager.createLoadBalancerRule("mytest3").getClass().getName());
-    Assert.assertEquals(SessionStickinessRule.class.getName(),
-        ExtensionsManager.createLoadBalancerRule("mytest4").getClass().getName());
-
-    System.getProperties().remove("servicecomb.loadbalance.mytest1.NFLoadBalancerRuleClassName");
-    System.getProperties().remove("servicecomb.loadbalance.mytest2.NFLoadBalancerRuleClassName");
-    System.getProperties().remove("servicecomb.loadbalance.mytest3.NFLoadBalancerRuleClassName");
-    System.getProperties().remove("servicecomb.loadbalance.mytest4.NFLoadBalancerRuleClassName");
-
     RetryHandler retryHandler = ExtensionsManager.createRetryHandler("mytest1");
     Assert.assertTrue(DefaultLoadBalancerRetryHandler.class.isInstance(retryHandler));
     Assert.assertFalse(retryHandler.isRetriableException(new InvocationException(400, "", ""), false));
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
index f088e718b..4c5373aa8 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
@@ -20,15 +20,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.servicecomb.core.Endpoint;
 import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.Transport;
 import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
+import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import org.junit.Assert;
 import org.junit.Test;
 
-import com.netflix.loadbalancer.RandomRule;
-import com.netflix.loadbalancer.RoundRobinRule;
 import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
 
 import mockit.Deencapsulation;
 import mockit.Expectations;
@@ -37,14 +37,21 @@
 
 public class TestLoadBalanceCreator {
   @Test
-  public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation invocation) {
+  public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation invocation,
+      @Injectable Transport transport) {
     // Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
-    RoundRobinRule rule = new RoundRobinRule();
-    List<Server> servers = new ArrayList<>();
-    Server server = new Server("host1", 80);
-    server.setAlive(true);
-    Server server2 = new Server("host2", 80);
-    server2.setAlive(true);
+    RoundRobinRuleExt rule = new RoundRobinRuleExt();
+    List<ServiceCombServer> servers = new ArrayList<>();
+    Endpoint host1 = new Endpoint(transport, "host1");
+    MicroserviceInstance instance1 = new MicroserviceInstance();
+    instance1.setInstanceId("instance1");
+    ServiceCombServer server = new ServiceCombServer(host1, instance1);
+
+    Endpoint host2 = new Endpoint(transport, "host2");
+    MicroserviceInstance instance2 = new MicroserviceInstance();
+    instance2.setInstanceId("instance2");
+    ServiceCombServer server2 = new ServiceCombServer(host2, instance2);
+
     servers.add(server);
     servers.add(server2);
     LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "test");
@@ -53,9 +60,10 @@ public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation in
 
     filters.add(new ServerListFilterExt() {
       @Override
-      public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
-        List<Server> filteredServers = new ArrayList<>();
-        for (Server server : servers) {
+      public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList,
+          Invocation invocation) {
+        List<ServiceCombServer> filteredServers = new ArrayList<>();
+        for (ServiceCombServer server : servers) {
           if (server.getHost().equals("host1")) {
             continue;
           }
@@ -66,35 +74,43 @@ public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation in
     });
     lbCreator.setFilters(filters);
 
-    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
-    Server s = lb.chooseServer("test");
+    LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+    Server s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
+    s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
+    s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
   }
 
   @Test
-  public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invocation) {
+  public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invocation,
+      @Injectable Transport transport) {
     // Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
-    RandomRule rule = new RandomRule();
+    RandomRuleExt rule = new RandomRuleExt();
     LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
 
-    List<Server> servers = new ArrayList<>();
-    Server server = new Server("host1", 80);
-    server.setAlive(true);
-    Server server2 = new Server("host2", 80);
-    server2.setAlive(true);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    Endpoint host1 = new Endpoint(transport, "host1");
+    MicroserviceInstance instance1 = new MicroserviceInstance();
+    instance1.setInstanceId("instance1");
+    ServiceCombServer server = new ServiceCombServer(host1, instance1);
+
+    Endpoint host2 = new Endpoint(transport, "host2");
+    MicroserviceInstance instance2 = new MicroserviceInstance();
+    instance2.setInstanceId("instance2");
+    ServiceCombServer server2 = new ServiceCombServer(host2, instance2);
+
     servers.add(server);
     servers.add(server2);
-    lbCreator.setServerList(servers);
+
     List<ServerListFilterExt> filters = new ArrayList<>();
     filters.add(new ServerListFilterExt() {
       @Override
-      public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
-        List<Server> filteredServers = new ArrayList<>();
-        for (Server server : servers) {
+      public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList,
+          Invocation invocation) {
+        List<ServiceCombServer> filteredServers = new ArrayList<>();
+        for (ServiceCombServer server : servers) {
           if (server.getHost().equals("host1")) {
             continue;
           }
@@ -104,46 +120,48 @@ public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invoca
       }
     });
     lbCreator.setFilters(filters);
-    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
-    Server s = lb.chooseServer("test");
+    LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+    Server s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
+    s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
+    s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
   }
 
   @Test
-  public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Mocked ServiceCombServer server,
-      @Mocked ServiceCombServer server2, @Injectable Invocation invocation) {
+  public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Injectable Endpoint endpoint1, @Injectable Endpoint endpoint2, @Injectable Invocation invocation) {
     // Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
-    WeightedResponseTimeRule rule = new WeightedResponseTimeRule();
+    WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
     LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
-    List<Server> servers = new ArrayList<>();
+
+
+    List<ServiceCombServer> servers = new ArrayList<>();
+    MicroserviceInstance instance1 = new MicroserviceInstance();
+    instance1.setInstanceId("ii01");
+    MicroserviceInstance instance2 = new MicroserviceInstance();
+    instance2.setInstanceId("ii02");
+    ServiceCombServer server = new ServiceCombServer(endpoint1, instance1);
+    ServiceCombServer server2 = new ServiceCombServer(endpoint2, instance2);
 
     new Expectations() {
       {
-        server.getHost();
+        endpoint1.getEndpoint();
         result = "host1";
-
-        server2.isReadyToServe();
-        result = true;
-        server2.isAlive();
-        result = true;
-        server2.getHost();
+        endpoint2.getEndpoint();
         result = "host2";
       }
     };
 
     servers.add(server);
     servers.add(server2);
-    lbCreator.setServerList(servers);
     List<ServerListFilterExt> filters = new ArrayList<>();
     filters.add(new ServerListFilterExt() {
       @Override
-      public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
-        List<Server> filteredServers = new ArrayList<>();
-        for (Server server : servers) {
+      public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList,
+          Invocation invocation) {
+        List<ServiceCombServer> filteredServers = new ArrayList<>();
+        for (ServiceCombServer server : servers) {
           if (server.getHost().equals("host1")) {
             continue;
           }
@@ -153,40 +171,47 @@ public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Mocked Service
       }
     });
     lbCreator.setFilters(filters);
-    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
-    Server s = lb.chooseServer("test");
+    LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+    Server s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
+    s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
+    s = lb.chooseServer(invocation);
     Assert.assertEquals(server2, s);
   }
 
   @Test
-  public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invocation) {
+  public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invocation,
+      @Injectable Transport transport) {
     SessionStickinessRule rule = new SessionStickinessRule();
     LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
 
-    List<Server> servers = new ArrayList<>();
-    Server server = new Server("host1", 80);
-    server.setAlive(true);
-    Server server2 = new Server("host2", 80);
-    server2.setAlive(true);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    Endpoint host1 = new Endpoint(transport, "host1");
+    MicroserviceInstance instance1 = new MicroserviceInstance();
+    ServiceCombServer server = new ServiceCombServer(host1, instance1);
+    instance1.setInstanceId("instance1");
+
+    Endpoint host2 = new Endpoint(transport, "host2");
+    MicroserviceInstance instance2 = new MicroserviceInstance();
+    ServiceCombServer server2 = new ServiceCombServer(host2, instance2);
+    instance2.setInstanceId("instance2");
+
     servers.add(server);
     servers.add(server2);
-    lbCreator.setServerList(servers);
+
     lbCreator.setFilters(new ArrayList<>());
-    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
-    Server s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
+    LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+    Server s = lb.chooseServer(invocation);
+    Assert.assertEquals(server, s);
+    s = lb.chooseServer(invocation);
+    Assert.assertEquals(server, s);
 
     long time = Deencapsulation.getField(rule, "lastAccessedTime");
     Deencapsulation.setField(rule, "lastAccessedTime", time - 1000 * 300);
     ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.sessionTimeoutInSeconds", 9);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server, s);
+    s = lb.chooseServer(invocation);
+    Assert.assertEquals(server2, s);
 
     ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.successiveFailedTimes", 5);
     lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
@@ -194,7 +219,7 @@ public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invoc
     lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
     lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
     lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
+    s = lb.chooseServer(invocation);
+    Assert.assertEquals(server, s);
   }
 }
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
index b5262b54c..906529fd2 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
@@ -35,6 +35,7 @@
 import org.apache.servicecomb.serviceregistry.discovery.DiscoveryTreeNode;
 import org.junit.After;
 import org.junit.Assert;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -43,6 +44,11 @@
  *
  */
 public class TestLoadBalanceHandler2 {
+  @BeforeClass
+  public static void beforeClass() {
+    // avoid mock
+    ServiceCombLoadBalancerStats.INSTANCE.init();
+  }
 
   @After
   public void teardown() {
@@ -122,54 +128,54 @@ public void testZoneAwareAndIsolationFilterWorks() {
 
     handler = new LoadbalanceHandler();
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server, null);
 
     data.put("noneMatchInstance", noneMatchInstance);
     parent.cacheVersion(1);
     handler = new LoadbalanceHandler();
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9092");
 
     data.put("regionMatchInstance", regionMatchInstance);
     parent.cacheVersion(parent.cacheVersion() + 1);
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
 
     data.put("allmatchInstance", allmatchInstance);
     parent.cacheVersion(parent.cacheVersion() + 1);
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
 
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
-    ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+    ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, 0);
 
     //if errorThresholdPercentage is 0,that means errorThresholdPercentage is not active.
     ArchaiusUtils.setProperty("servicecomb.loadbalance.isolation.errorThresholdPercentage", "0");
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
 
     //if errorThresholdPercentage greater than 0, it will activate.
     ArchaiusUtils.setProperty("servicecomb.loadbalance.isolation.errorThresholdPercentage", "20");
     ServiceCombServer server2 = server;
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server2);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server2, 0);
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
-    ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2);
-    ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2);
+    ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2, 0);
+    ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2, 0);
     loadBalancer = handler.getOrCreateLoadBalancer(invocation);
-    server = (ServiceCombServer) loadBalancer.chooseServer();
+    server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
     Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
   }
 }
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
index a61fa4fa2..7b26368bf 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
@@ -17,117 +17,31 @@
 
 package org.apache.servicecomb.loadbalance;
 
-import static org.junit.Assert.assertNotNull;
-
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.servicecomb.core.Invocation;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
-import com.netflix.loadbalancer.AbstractLoadBalancer.ServerGroup;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.Server;
-
 public class TestLoadBalancer {
-  private IRule rule = Mockito.mock(IRule.class);
+  private RuleExt rule = Mockito.mock(RuleExt.class);
 
-  @SuppressWarnings("deprecation")
   @Test
   public void testLoadBalancerFullOperationWithoutException() {
-    List<Server> newServers = new ArrayList<>();
-    Server server = Mockito.mock(Server.class);
+    List<ServiceCombServer> newServers = new ArrayList<>();
+    ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+    Invocation invocation = Mockito.mock(Invocation.class);
     newServers.add(server);
-    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
-    loadBalancer.setServerList(newServers);
-    loadBalancer.chooseServer();
-
-    Object key = Mockito.mock(Object.class);
+    List<ServerListFilterExt> filterExts = new ArrayList<>();
+    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null, filterExts, newServers);
+    loadBalancer.chooseServer(invocation);
 
-    loadBalancer.chooseServer(key);
-    loadBalancer.getAllServers();
-    loadBalancer.getServerList(true);
-    loadBalancer.getServerList(false);
-    loadBalancer.getLoadBalancerStats();
-    loadBalancer.getReachableServers();
-
-    assertNotNull(loadBalancer.getAllServers());
-  }
-
-  @Test
-  public void testAddServerException() {
-    boolean status = true;
-    List<Server> newServers = new ArrayList<>();
-    Server server = Mockito.mock(Server.class);
-
-    newServers.add(server);
-    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
-    loadBalancer.setServerList(newServers);
-    try {
+    Mockito.when(rule.choose(newServers, invocation)).thenReturn(server);
 
-      loadBalancer.addServers(newServers);
-    } catch (Exception e) {
-
-      status = false;
-
-      Assert.assertEquals("Not implemented.", e.getMessage());
-    }
-
-    Assert.assertFalse(status);
-  }
-
-  @Test
-  public void testServerListException() {
-    boolean status = true;
-    List<Server> newServers = new ArrayList<>();
-    Server server = Mockito.mock(Server.class);
-
-    newServers.add(server);
-    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
-    loadBalancer.setServerList(newServers);
-    try {
-
-      loadBalancer.getServerList(ServerGroup.ALL);
-    } catch (Exception e) {
-
-      status = false;
-
-      Assert.assertEquals("Not implemented.", e.getMessage());
-    }
-
-    Assert.assertFalse(status);
-  }
-
-  @Test
-  public void testMarkServerDownException() {
-    boolean status = true;
-    List<Server> newServers = new ArrayList<>();
-    Server server = Mockito.mock(Server.class);
-
-    newServers.add(server);
-    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
-    loadBalancer.setServerList(newServers);
-    try {
-
-      loadBalancer.markServerDown(server);
-    } catch (Exception e) {
-
-      status = false;
-
-      Assert.assertEquals("Not implemented.", e.getMessage());
-    }
-
-    Assert.assertFalse(status);
-  }
-
-  @Test
-  public void testGetAllServers() {
-    List<Server> servers = new ArrayList<>();
-    Server server = Mockito.mock(Server.class);
-    servers.add(server);
-    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
-    loadBalancer.setServerList(servers);
-    Assert.assertEquals(servers, loadBalancer.getAllServers());
+    Assert.assertEquals(server, loadBalancer.chooseServer(invocation));
+    Assert.assertEquals(null, loadBalancer.getLoadBalancerStats());
+    Assert.assertEquals("test", loadBalancer.getMicroServiceName());
   }
 }
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
index faa86f961..468e48226 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
@@ -137,7 +137,6 @@ InstanceCacheManager getInstanceCacheManager() {
 
     BeansHolder holder = new BeansHolder();
     List<ExtensionsFactory> extensionsFactories = new ArrayList<>();
-    extensionsFactories.add(new RuleClassNameExtentionsFactory());
     extensionsFactories.add(new RuleNameExtentionsFactory());
     extensionsFactories.add(new DefaultRetryExtensionsFactory());
     Deencapsulation.setField(holder, "extentionsFactories", extensionsFactories);
@@ -179,7 +178,7 @@ public void getOrCreateLoadBalancer() throws Exception {
 
     LoadBalancer lb = handler.getOrCreateLoadBalancer(invocation);
 
-    Assert.assertEquals("[rest://localhost:8080]", Deencapsulation.getField(lb, "serverList").toString());
+    Assert.assertEquals("[rest://localhost:8080]", Deencapsulation.getField(lb, "servers").toString());
   }
 
   @Test
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
index 11dfe77bb..23352c8e2 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
@@ -39,7 +39,7 @@
   @BeforeClass
   public static void beforeClass() {
     // avoid mock
-    ServiceCombLoadBalancerStats.INSTANCE.getClass();
+    ServiceCombLoadBalancerStats.INSTANCE.init();
   }
 
   @Test
@@ -64,7 +64,7 @@ public void testServiceExpire(@Injectable Transport transport, @Mocked SPIServic
 
     ServiceCombServer serviceCombServer = new ServiceCombServer(transport,
         new CacheEndpoint("rest://localhost:8080", instance));
-    serviceCombLoadBalancerStats.markSuccess(serviceCombServer);
+    serviceCombLoadBalancerStats.markSuccess(serviceCombServer, 0);
     ServiceCombServerStats stats = serviceCombLoadBalancerStats.getServiceCombServerStats(serviceCombServer);
     Assert.assertEquals(serviceCombLoadBalancerStats.getPingView().size(), 1);
     await().atMost(5, TimeUnit.SECONDS)
@@ -83,16 +83,16 @@ public void testSimpleThread(@Injectable Transport transport) {
     instance.setInstanceId("instance1");
     ServiceCombServer serviceCombServer = new ServiceCombServer(transport,
         new CacheEndpoint("rest://localhost:8080", instance));
-    ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
-    ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
+    ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+    ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
     Assert.assertEquals(
         ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getCountinuousFailureCount(),
         2);
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
     Assert.assertEquals(
         ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getCountinuousFailureCount(),
         0);
-    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+    ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
     Assert
         .assertEquals(
             ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getTotalRequests(), 4);
@@ -119,10 +119,10 @@ public void testMiltiThread(@Injectable Transport transport) throws Exception {
     for (int i = 0; i < 10; i++) {
       new Thread() {
         public void run() {
-          ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
-          ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
-          ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
-          ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+          ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+          ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+          ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
+          ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
           latch.countDown();
         }
       }.start();
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
index 301036872..3fda33900 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
@@ -31,12 +31,12 @@
   public void testSimpleThread() {
     long time = System.currentTimeMillis();
     ServiceCombServerStats stats = new ServiceCombServerStats();
-    stats.markFailure();
-    stats.markFailure();
+    stats.markFailure(0);
+    stats.markFailure(0);
     Assert.assertEquals(stats.getCountinuousFailureCount(), 2);
-    stats.markSuccess();
+    stats.markSuccess(0);
     Assert.assertEquals(stats.getCountinuousFailureCount(), 0);
-    stats.markSuccess();
+    stats.markSuccess(0);
     Assert.assertEquals(stats.getTotalRequests(), 4);
     Assert.assertEquals(stats.getFailedRate(), 50);
     Assert.assertEquals(stats.getSuccessRate(), 50);
@@ -52,10 +52,10 @@ public void testMiltiThread() throws Exception {
     for (int i = 0; i < 10; i++) {
       new Thread() {
         public void run() {
-          stats.markFailure();
-          stats.markFailure();
-          stats.markSuccess();
-          stats.markSuccess();
+          stats.markFailure(0);
+          stats.markFailure(0);
+          stats.markSuccess(0);
+          stats.markSuccess(0);
           latch.countDown();
         }
       }.start();
@@ -78,8 +78,8 @@ long currentTimeMillis() {
     };
     ServiceCombServerStats stats = new ServiceCombServerStats();
     Assert.assertEquals(stats.getLastVisitTime(), 1000);
-    stats.markSuccess();
-    stats.markFailure();
+    stats.markSuccess(0);
+    stats.markFailure(0);
     Assert.assertEquals(stats.getTotalRequests(), 2);
     Assert.assertEquals(stats.getFailedRate(), 50);
     Assert.assertEquals(stats.getSuccessRate(), 50);
@@ -89,7 +89,7 @@ long currentTimeMillis() {
         return 60000 + 2000;
       }
     };
-    stats.markSuccess();
+    stats.markSuccess(0);
     Assert.assertEquals(stats.getTotalRequests(), 1);
     Assert.assertEquals(stats.getFailedRate(), 0);
     Assert.assertEquals(stats.getSuccessRate(), 100);
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
index 6ebead209..dd2319e1b 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
@@ -20,9 +20,11 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.Transport;
 import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import org.apache.servicecomb.serviceregistry.cache.CacheEndpoint;
@@ -49,22 +51,20 @@ public void testRuleFullOperation() {
     instance1.setInstanceId("1234");
     ServiceCombServer mockedServer =
         new ServiceCombServer(transport, new CacheEndpoint("rest:127.0.0.1:8889", instance1));
-    Object key = Mockito.mock(Object.class);
+    Invocation invocation = mock(Invocation.class);
     LoadBalancerStats stats = mock(LoadBalancerStats.class);
     Mockito.when(mockedLb.getLoadBalancerStats()).thenReturn(stats);
-    Deencapsulation.invoke(rule, "chooseServerWhenTimeout", key);
+    Deencapsulation.invoke(rule, "chooseServerWhenTimeout", Arrays.asList(mockedServer), invocation);
     mockedServer.setAlive(true);
     mockedServer.setReadyToServe(true);
-    List<Server> allServers = Arrays.asList(mockedServer);
-    when(mockedLb.getReachableServers()).thenReturn(allServers);
-    when(mockedLb.getAllServers()).thenReturn(allServers);
-
+    List<ServiceCombServer> allServers = Arrays.asList(mockedServer);
     rule.setLoadBalancer(mockedLb);
-    Assert.assertEquals(rule.getLoadBalancer(), mockedLb);
-    Server s = rule.choose("default");
+
+
+    Server s = rule.choose(allServers, invocation);
     Assert.assertEquals(s, mockedServer);
 
-    s = rule.choose("default");
+    s = rule.choose(allServers, invocation);
     Assert.assertEquals(s, mockedServer);
   }
 
@@ -77,9 +77,12 @@ public void testServerWithoutTimeoutAndWithThreshold() {
 
     Object key = new Object();
 
-    Server s = new Server("test");
+    Invocation invocation = mock(Invocation.class);
+    ServiceCombServer server = mock(ServiceCombServer.class);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    servers.add(server);
 
-    Deencapsulation.setField(ss, "lastServer", s);
+    Deencapsulation.setField(ss, "lastServer", server);
 
     new MockUp<SessionStickinessRule>() {
 
@@ -98,7 +101,7 @@ private boolean isErrorThresholdMet() {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -112,11 +115,12 @@ public void testServerWithTimeout() {
 
     SessionStickinessRule ss = new SessionStickinessRule();
 
-    Object key = new Object();
-
-    Server s = new Server("test");
+    Invocation invocation = mock(Invocation.class);
+    ServiceCombServer server = mock(ServiceCombServer.class);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    servers.add(server);
 
-    Deencapsulation.setField(ss, "lastServer", s);
+    Deencapsulation.setField(ss, "lastServer", server);
 
     new MockUp<SessionStickinessRule>() {
 
@@ -127,7 +131,7 @@ private boolean isTimeOut() {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -144,9 +148,12 @@ public void testServerWithoutTimeoutException() {
 
     Object key = new Object();
 
-    Server s = new Server("test");
+    Invocation invocation = mock(Invocation.class);
+    ServiceCombServer server = mock(ServiceCombServer.class);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    servers.add(server);
 
-    Deencapsulation.setField(ss, "lastServer", s);
+    Deencapsulation.setField(ss, "lastServer", server);
 
     new MockUp<SessionStickinessRule>() {
 
@@ -157,7 +164,7 @@ private boolean isTimeOut() {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -173,9 +180,12 @@ public void testServerWithoutTimeoutAndThreshold() {
 
     Object key = new Object();
 
-    Server s = new Server("test");
+    Invocation invocation = mock(Invocation.class);
+    ServiceCombServer server = mock(ServiceCombServer.class);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    servers.add(server);
 
-    Deencapsulation.setField(ss, "lastServer", s);
+    Deencapsulation.setField(ss, "lastServer", server);
 
     new MockUp<SessionStickinessRule>() {
 
@@ -202,7 +212,7 @@ private boolean isLastServerExists(Server server) {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -217,26 +227,14 @@ public void testServerWithActualServerObj() {
 
     Object key = new Object();
 
-    Server s = new Server("test");
+    Invocation invocation = mock(Invocation.class);
+    ServiceCombServer server = mock(ServiceCombServer.class);
+    List<ServiceCombServer> servers = new ArrayList<>();
+    servers.add(server);
 
-    Deencapsulation.setField(ss, "lastServer", s);
-    try {
-      ss.choose(key);
-    } catch (Exception e) {
-      status = false;
-    }
-    Assert.assertTrue(status);
-  }
-
-  @Test
-  public void testServerWithKey() {
-
-    boolean status = true;
-    SessionStickinessRule ss = new SessionStickinessRule();
-
-    Object key = new Object();
+    Deencapsulation.setField(ss, "lastServer", server);
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -248,6 +246,7 @@ public void testLastServerNotExist() {
     SessionStickinessRule rule = new SessionStickinessRule();
 
     Transport transport = mock(Transport.class);
+    Invocation invocation = mock(Invocation.class);
     MicroserviceInstance instance1 = new MicroserviceInstance();
     instance1.setInstanceId("1234");
     ServiceCombServer mockedServer =
@@ -255,13 +254,11 @@ public void testLastServerNotExist() {
     mockedServer.setAlive(true);
     mockedServer.setReadyToServe(true);
     mockedServer.setId("mockedServer");
-    List<Server> allServers = Arrays.asList(mockedServer);
-    LoadBalancer lb = new LoadBalancer(rule, "mockedServer", null);
-    lb.setServerList(allServers);
+    List<ServiceCombServer> allServers = Arrays.asList(mockedServer);
+    LoadBalancer lb = new LoadBalancer(rule, "mockedServer", null, new ArrayList<>(), allServers);
 
     rule.setLoadBalancer(lb);
-    Assert.assertEquals(lb, rule.getLoadBalancer());
-    Server server = new Server("test");
+    ServiceCombServer server = new ServiceCombServer(transport, new CacheEndpoint("rest:127.0.0.1:8890", instance1));
     Deencapsulation.setField(rule, "lastServer", server);
 
     new MockUp<SessionStickinessRule>(rule) {
@@ -276,7 +273,7 @@ private boolean isErrorThresholdMet() {
       }
     };
     Object key = Mockito.mock(Object.class);
-    Server s = rule.choose(key);
+    Server s = rule.choose(allServers, invocation);
     Assert.assertEquals(mockedServer, s);
   }
 }
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
index 3a5e8b959..5dbd6a45c 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
@@ -72,6 +72,7 @@ public void createEndpointNormal() {
       }
     };
     MicroserviceInstance instance = new MicroserviceInstance();
+    instance.setInstanceId("0000001");
 
     ServiceCombServer server = (ServiceCombServer) filter.createEndpoint(Const.RESTFUL, "rest://localhost:8080", instance);
     Assert.assertSame(instance, server.getInstance());
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
index 5c3caf091..30e812fca 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
@@ -21,13 +21,17 @@
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 
+import javax.ws.rs.core.Response.Status;
+
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
 import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper;
 import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
 import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension;
 import org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;
 
@@ -159,6 +163,10 @@ public Response doInvoke(SwaggerInvocation invocation) {
       }
       Object result = producerMethod.invoke(producerInstance, args);
       response = responseMapper.mapResponse(invocation.getStatus(), result);
+    } catch (IllegalArgumentException ae) {
+      response = processException(invocation,
+          new InvocationException(Status.BAD_REQUEST.getStatusCode(), "",
+              new CommonExceptionData(ae.getMessage()), ae));
     } catch (Throwable e) {
       response = processException(invocation, e);
     }


 

----------------------------------------------------------------
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