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

liubao pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 1878b4b3d0b79963e6892592be0ce32fa537da78
Author: liubao <[email protected]>
AuthorDate: Fri Aug 24 21:40:40 2018 +0800

    [SBC-870]refractor to using custom RuleExt, not using Robin IRule.
---
 .../common/rest/codec/RestObjectMapper.java        |   2 +
 .../jaxrs/client/CodeFirstRestTemplateJaxrs.java   |   2 +-
 .../client/CustomLoadbalanceExtensionsFactory.java |   6 +-
 .../src/main/resources/microservice.yaml           |   4 +-
 .../demo/springmvc/client/SpringmvcClient.java     |  12 ++
 .../src/main/resources/microservice.yaml           |   3 +-
 .../servicecomb/loadbalance/Configuration.java     |  10 --
 .../servicecomb/loadbalance/ExtensionsFactory.java |   2 +-
 .../servicecomb/loadbalance/ExtensionsManager.java |  14 +-
 .../servicecomb/loadbalance/LoadBalancer.java      |  78 +++-------
 .../loadbalance/LoadBalancerCreator.java           |  44 +-----
 .../loadbalance/LoadbalanceHandler.java            |  48 +++----
 .../servicecomb/loadbalance/RandomRuleExt.java}    |  20 +--
 .../loadbalance/RoundRobinRuleExt.java}            |  20 +--
 .../RuleClassNameExtentionsFactory.java            |  62 --------
 .../apache/servicecomb/loadbalance/RuleExt.java}   |  17 +--
 .../loadbalance/RuleNameExtentionsFactory.java     |  12 +-
 .../loadbalance/ServerListFilterExt.java           |  12 +-
 .../loadbalance/ServiceCombLoadBalancerStats.java  |  23 ++-
 .../servicecomb/loadbalance/ServiceCombServer.java |  16 +++
 .../loadbalance/ServiceCombServerStats.java        |  19 ++-
 .../loadbalance/SessionStickinessRule.java         |  70 ++++-----
 .../loadbalance/WeightedResponseTimeRuleExt.java   |  65 +++++++++
 .../loadbalance/MyServerListFilterExt.java         |   2 +-
 .../servicecomb/loadbalance/TestConfiguration.java |   2 -
 .../loadbalance/TestExtensionsManager.java         |  31 +---
 .../loadbalance/TestLoadBalanceCreator.java        | 159 ++++++++++++---------
 .../loadbalance/TestLoadBalanceHandler2.java       |  38 ++---
 .../servicecomb/loadbalance/TestLoadBalancer.java  | 110 ++------------
 .../loadbalance/TestLoadbalanceHandler.java        |   3 +-
 .../TestServiceCombLoadBalancerStats.java          |  20 +--
 .../loadbalance/TestServiceCombServerStats.java    |  22 +--
 .../loadbalance/TestSessionSticknessRule.java      |  91 ++++++------
 .../filter/TestServerDiscoveryFilter.java          |   1 +
 .../swagger/engine/SwaggerProducerOperation.java   |   8 ++
 35 files changed, 455 insertions(+), 593 deletions(-)

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 f94ec2c..327175b 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 class RestObjectMapper extends 
AbstractRestObjectMapper {
     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 38ae6e9..2481e52 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 @@ public class CodeFirstRestTemplateJaxrs extends 
CodeFirstRestTemplate {
   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 cb0eef6..c015165 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 @@ package org.apache.servicecomb.demo.jaxrs.client;
 
 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 @@ import com.netflix.loadbalancer.RoundRobinRule;
 @Component
 public class CustomLoadbalanceExtensionsFactory implements ExtensionsFactory {
 
-  class MyCustomRule extends RoundRobinRule {
+  class MyCustomRule extends RoundRobinRuleExt {
 
   }
 
@@ -56,7 +58,7 @@ public class CustomLoadbalanceExtensionsFactory implements 
ExtensionsFactory {
   }
 
   @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 89f324c..c4bbcdd 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-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 3e5aa1c..2a41e0a 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 class SpringmvcClient {
   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 2290b6f..03b137c 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 f2f8f62..2268855 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 final class Configuration {
 
   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 @@ public final class Configuration {
   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 fa97372..9077575 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 @@ import com.netflix.loadbalancer.IRule;
 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 15edefe..2df0395 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.Logger;
 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 class ExtensionsManager {
     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 class ExtensionsManager {
     }
 
     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 56db6ff..3a96b59 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 eedbb9c..5cb18dc 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 @@ import com.netflix.loadbalancer.WeightedResponseTimeRule;
  *  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 @@ public class LoadBalancerCreator {
 
   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 class LoadBalancerCreator {
   }
 
   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 @@ public class LoadBalancerCreator {
     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 7d6394a..06f4b10 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.Logger;
 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 com.netflix.loadbalancer.reactive.ServerOperation;
 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 @@ public class LoadbalanceHandler implements Handler {
 
     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 class LoadbalanceHandler implements Handler {
 
     @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 class LoadbalanceHandler implements Handler {
 
   private final Object lock = new Object();
 
-  private String policy = null;
-
   private String strategy = null;
 
 
@@ -148,16 +146,13 @@ public class LoadbalanceHandler implements Handler {
 
   @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 @@ public class LoadbalanceHandler implements Handler {
       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 class LoadbalanceHandler implements Handler {
     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 class LoadbalanceHandler implements Handler {
                     ((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 @@ public class LoadbalanceHandler implements Handler {
     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/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
similarity index 72%
copy from 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
copy to 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
index ed08789..60eedac 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
@@ -17,23 +17,23 @@
 
 package org.apache.servicecomb.loadbalance;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.Random;
 
 import org.apache.servicecomb.core.Invocation;
 
-import com.netflix.loadbalancer.Server;
-
 /**
- * @author l00168639
- *
+ * A random rule.
  */
-public class MyServerListFilterExt implements ServerListFilterExt {
+public class RandomRuleExt implements RuleExt {
+  private Random random = new Random();
+
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> serverList, 
Invocation invocation) {
-    if (invocation.getAppId().equals("test")) {
-      return new ArrayList<>();
+  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation 
invocation) {
+    if (servers.size() == 0) {
+      return null;
     }
-    return serverList;
+    int index = Math.abs(random.nextInt()) % servers.size();
+    return servers.get(index);
   }
 }
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
similarity index 69%
copy from 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
copy to 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
index ed08789..c3a887d 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
@@ -17,23 +17,23 @@
 
 package org.apache.servicecomb.loadbalance;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.servicecomb.core.Invocation;
 
-import com.netflix.loadbalancer.Server;
-
 /**
- * @author l00168639
- *
+ * A round robin rule
  */
-public class MyServerListFilterExt implements ServerListFilterExt {
+public class RoundRobinRuleExt implements RuleExt {
+  private AtomicInteger counter = new AtomicInteger(0);
+
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> serverList, 
Invocation invocation) {
-    if (invocation.getAppId().equals("test")) {
-      return new ArrayList<>();
+  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation 
invocation) {
+    if (servers.size() == 0) {
+      return null;
     }
-    return serverList;
+    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 b6df5ef..0000000
--- 
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/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
similarity index 71%
copy from 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
copy to 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
index ed08789..a95ccbc 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
@@ -17,23 +17,16 @@
 
 package org.apache.servicecomb.loadbalance;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.servicecomb.core.Invocation;
 
-import com.netflix.loadbalancer.Server;
-
 /**
- * @author l00168639
- *
+ * Load balance rule to support invocation based filters.
  */
-public class MyServerListFilterExt implements ServerListFilterExt {
-  @Override
-  public List<Server> getFilteredListOfServers(List<Server> serverList, 
Invocation invocation) {
-    if (invocation.getAppId().equals("test")) {
-      return new ArrayList<>();
-    }
-    return serverList;
+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 92d5be2..5ab7cfb 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 java.util.Collection;
 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 class RuleNameExtentionsFactory implements 
ExtensionsFactory {
   }
 
   @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 7695a68..9dba004 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 java.util.List;
 
 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 1b7be1d..ac01152 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 class ServiceCombLoadBalancerStats {
 
   public static final ServiceCombLoadBalancerStats INSTANCE;
 
+  private Timer timer;
+
   static {
     INSTANCE = new ServiceCombLoadBalancerStats();
     INSTANCE.init();
@@ -76,17 +78,17 @@ public class ServiceCombLoadBalancerStats {
     }
   }
 
-  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 @@ public class ServiceCombLoadBalancerStats {
   }
 
   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 class ServiceCombLoadBalancerStats {
                   }
                 });
 
-    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 class ServiceCombLoadBalancerStats {
           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 1d4edf3..800e2ae 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.core.Transport;
 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 @@ public class ServiceCombServer extends Server {
   // 所属服务实例
   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 b33771b..03b458e 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 @@ public class ServiceCombServerStats {
 
   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 @@ public class ServiceCombServerStats {
             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 d589b4d..a489860 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 @@ import com.netflix.loadbalancer.ServerStats;
  * 提供当会话过期或者失败次数超过限制后,轮询选择其他服务器的能力。
  *
  */
-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 @@ public class SessionStickinessRule implements IRule {
   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 @@ public class SessionStickinessRule implements IRule {
   }
 
   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 @@ public class SessionStickinessRule implements IRule {
   }
 
   @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 class SessionStickinessRule implements IRule {
     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 0000000..06aba4f
--- /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 ed08789..6f93b44 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 @@ import com.netflix.loadbalancer.Server;
  */
 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 08d498d..6ef2160 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 class TestConfiguration {
   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 class TestConfiguration {
 
   @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 69c4a1e..169e91a 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 class TestExtensionsManager {
 
     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 class TestExtensionsManager {
 
   @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 f088e71..4c5373a 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 @@ package org.apache.servicecomb.loadbalance;
 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 @@ import mockit.Mocked;
 
 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 class TestLoadBalanceCreator {
 
     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 class TestLoadBalanceCreator {
     });
     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 class TestLoadBalanceCreator {
       }
     });
     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 class TestLoadBalanceCreator {
       }
     });
     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 class TestLoadBalanceCreator {
     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 b5262b5..906529f 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.cache.InstanceCacheManager;
 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 @@ import org.mockito.Mockito;
  *
  */
 public class TestLoadBalanceHandler2 {
+  @BeforeClass
+  public static void beforeClass() {
+    // avoid mock
+    ServiceCombLoadBalancerStats.INSTANCE.init();
+  }
 
   @After
   public void teardown() {
@@ -122,54 +128,54 @@ public class TestLoadBalanceHandler2 {
 
     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 a61fa4f..7b26368 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 faa86f9..468e482 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 @@ public class TestLoadbalanceHandler {
 
     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 class TestLoadbalanceHandler {
 
     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 11dfe77..23352c8 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 @@ public class TestServiceCombLoadBalancerStats {
   @BeforeClass
   public static void beforeClass() {
     // avoid mock
-    ServiceCombLoadBalancerStats.INSTANCE.getClass();
+    ServiceCombLoadBalancerStats.INSTANCE.init();
   }
 
   @Test
@@ -64,7 +64,7 @@ public class TestServiceCombLoadBalancerStats {
 
     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 class TestServiceCombLoadBalancerStats {
     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 class TestServiceCombLoadBalancerStats {
     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 3010368..3fda339 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 class TestServiceCombServerStats {
   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 class TestServiceCombServerStats {
     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 @@ public class TestServiceCombServerStats {
     };
     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 @@ public class TestServiceCombServerStats {
         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 6ebead2..dd2319e 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 @@ package org.apache.servicecomb.loadbalance;
 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 class TestSessionSticknessRule {
     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 class TestSessionSticknessRule {
 
     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 @@ public class TestSessionSticknessRule {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -112,11 +115,12 @@ public class TestSessionSticknessRule {
 
     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 @@ public class TestSessionSticknessRule {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -144,9 +148,12 @@ public class TestSessionSticknessRule {
 
     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 @@ public class TestSessionSticknessRule {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -173,9 +180,12 @@ public class TestSessionSticknessRule {
 
     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 @@ public class TestSessionSticknessRule {
     };
 
     try {
-      ss.choose(key);
+      ss.choose(servers, invocation);
     } catch (Exception e) {
       status = false;
     }
@@ -217,26 +227,14 @@ public class TestSessionSticknessRule {
 
     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 class TestSessionSticknessRule {
     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 class TestSessionSticknessRule {
     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 @@ public class TestSessionSticknessRule {
       }
     };
     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 3a5e8b9..5dbd6a4 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 class TestServerDiscoveryFilter {
       }
     };
     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 5c3caf0..30e812f 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.lang.reflect.Method;
 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 class SwaggerProducerOperation {
       }
       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);
     }

Reply via email to