[ 
https://issues.apache.org/jira/browse/SCB-706?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16540250#comment-16540250
 ] 

ASF GitHub Bot commented on SCB-706:
------------------------------------

liubao68 closed pull request #786: [SCB-706]refactor loadbalance filters logic 
to support invocation based filter
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/786
 
 
   

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

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

diff --git 
a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml 
b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
index 09a4d0e69..ce89ac481 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
@@ -54,10 +54,6 @@ servicecomb:
     retryEnabled: true
     retryOnSame: 1
     retryOnNext: 1
-    serverListFilters: zoneaware
-    serverListFilter:
-      zoneaware:
-        className: 
org.apache.servicecomb.loadbalance.filter.ZoneAwareServerListFilterExt
   fallbackpolicy:
     Consumer:
       springmvc:
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 22f8b19bb..51bcc682b 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
@@ -19,59 +19,32 @@
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.servicecomb.core.Invocation;
 
 import com.netflix.loadbalancer.AbstractLoadBalancer;
 import com.netflix.loadbalancer.IRule;
 import com.netflix.loadbalancer.LoadBalancerStats;
 import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.ServerListFilter;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
 
 /**
- * 实现不包含服务器状态监测的负载均衡器。(这些职责在注册中心客户端实现)
- *
+ *  Robbin LoadBalancer implementation. Only support IRule and basic 
operations.
  */
 public class LoadBalancer extends AbstractLoadBalancer {
-  private String name;
-
   private List<Server> serverList = Collections.emptyList();
 
   private IRule rule;
 
   private LoadBalancerStats lbStats;
 
-  // 以filter类名为Key
-  private Map<String, ServerListFilterExt> filters;
-
   private String microServiceName;
 
-  public LoadBalancer(String name, IRule rule, String microServiceName) {
-    this.name = name;
-    this.rule = rule;
+  public LoadBalancer(IRule rule, String microServiceName,
+      LoadBalancerStats stats) {
     this.microServiceName = microServiceName;
-    this.lbStats = new LoadBalancerStats(null);
-    this.filters = new ConcurrentHashMap<>();
+    this.rule = rule;
     this.rule.setLoadBalancer(this);
+    this.lbStats = stats;
   }
 
-  public String getName() {
-    return name;
-  }
-
-  public void shutdown() {
-    // netflix components does not have a property 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) {
     this.serverList = Collections.unmodifiableList(serverList);
   }
@@ -103,12 +76,14 @@ public void markServerDown(Server server) {
   }
 
   @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() {
-    List<Server> servers = serverList;
-    for (ServerListFilter<Server> filter : filters.values()) {
-      servers = filter.getFilteredListOfServers(servers);
-    }
-    return servers;
+    return serverList;
   }
 
   @Override
@@ -121,20 +96,6 @@ public LoadBalancerStats getLoadBalancerStats() {
     return lbStats;
   }
 
-  public void setInvocation(Invocation invocation) {
-    for (ServerListFilterExt filter : filters.values()) {
-      filter.setInvocation(invocation);
-    }
-  }
-
-  public void putFilter(String name, ServerListFilterExt filter) {
-    filters.put(name, filter);
-  }
-
-  public int getFilterSize() {
-    return filters.size();
-  }
-
   public String getMicroServiceName() {
     return microServiceName;
   }
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
new file mode 100644
index 000000000..78baad4ac
--- /dev/null
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
@@ -0,0 +1,93 @@
+/*
+ * 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.Collections;
+import java.util.List;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+
+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.
+ *
+ *  Robin components work good in service level state, and we want to reuse 
its IRule components and other
+ *  facilities, but they are not good for operation
+ *  level filters, so write a custom load balance process.
+ *
+ *  Load balance instance is created for each microservice(plus version rule), 
thus it is service level,
+ *  it only can contains stateful information with service. e.g. 
LoadBalancerStats.
+ *
+ *  ServerListFilter may choose available servers according to invocation 
information, IRule will work
+ *  on the result of ServerListFilter, they should not contain operation level 
state information in instance fields.
+ */
+public class LoadBalancerCreator {
+  private List<Server> serverList = Collections.emptyList();
+
+  private IRule rule;
+
+  private LoadBalancerStats lbStats;
+
+  private List<ServerListFilterExt> filters;
+
+  private String microServiceName;
+
+  public LoadBalancerCreator(IRule rule, String microServiceName) {
+    this.rule = rule;
+    this.microServiceName = microServiceName;
+    this.lbStats = new LoadBalancerStats(null);
+    // load new instances, because filters work on service information
+    this.filters = 
SPIServiceUtils.loadSortedService(ServerListFilterExt.class);
+  }
+
+  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) {
+    this.serverList = Collections.unmodifiableList(serverList);
+  }
+
+  @VisibleForTesting
+  void setFilters(List<ServerListFilterExt> filters) {
+    this.filters = filters;
+  }
+
+  public LoadBalancer createLoadBalancer(Invocation invocation) {
+    LoadBalancer loadBalancer = new LoadBalancer(rule, microServiceName, 
lbStats);
+    List<Server> servers = this.serverList;
+    for (ServerListFilterExt filter : this.filters) {
+      filter.setLoadBalancer(loadBalancer);
+      servers = filter.getFilteredListOfServers(servers, invocation);
+    }
+    loadBalancer.setServerList(servers);
+    return loadBalancer;
+  }
+}
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 06ffb9bc1..a8d61b6cc 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
@@ -33,9 +33,7 @@
 import org.apache.servicecomb.core.provider.consumer.SyncResponseExecutor;
 import org.apache.servicecomb.foundation.common.cache.VersionedCache;
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
-import org.apache.servicecomb.loadbalance.filter.CseServerDiscoveryFilter;
-import org.apache.servicecomb.loadbalance.filter.IsolationServerListFilter;
-import org.apache.servicecomb.loadbalance.filter.TransactionControlFilter;
+import org.apache.servicecomb.loadbalance.filter.ServerDiscoveryFilter;
 import org.apache.servicecomb.serviceregistry.discovery.DiscoveryContext;
 import org.apache.servicecomb.serviceregistry.discovery.DiscoveryFilter;
 import org.apache.servicecomb.serviceregistry.discovery.DiscoveryTree;
@@ -78,7 +76,7 @@ public Thread newThread(Runnable r) {
   private DiscoveryTree discoveryTree = new DiscoveryTree();
 
   // key为grouping filter qualified name
-  private volatile Map<String, LoadBalancer> loadBalancerMap = new 
ConcurrentHashMapEx<>();
+  private volatile Map<String, LoadBalancerCreator> loadBalancerMap = new 
ConcurrentHashMapEx<>();
 
   private final Object lock = new Object();
 
@@ -89,7 +87,7 @@ public Thread newThread(Runnable r) {
 
   public LoadbalanceHandler() {
     discoveryTree.loadFromSPI(DiscoveryFilter.class);
-    discoveryTree.addFilter(new CseServerDiscoveryFilter());
+    discoveryTree.addFilter(new ServerDiscoveryFilter());
     discoveryTree.sort();
   }
 
@@ -107,10 +105,6 @@ public void handle(Invocation invocation, AsyncResponse 
asyncResp) throws Except
     this.policy = policy;
     this.strategy = strategy;
     LoadBalancer loadBalancer = getOrCreateLoadBalancer(invocation);
-    // TODO: after all old filter moved to new filter
-    // setInvocation method must to be removed
-    // invocation是请求级别的,因此每次调用都需要设置一次
-    loadBalancer.setInvocation(invocation);
 
     if 
(!Configuration.INSTANCE.isRetryEnabled(invocation.getMicroserviceName())) {
       send(invocation, asyncResp, loadBalancer);
@@ -120,49 +114,23 @@ public void handle(Invocation invocation, AsyncResponse 
asyncResp) throws Except
   }
 
   private void clearLoadBalancer() {
-    for (LoadBalancer loadBalancer : loadBalancerMap.values()) {
-      loadBalancer.shutdown();
+    for (LoadBalancerCreator creator : loadBalancerMap.values()) {
+      creator.shutdown();
     }
     loadBalancerMap.clear();
   }
 
-  protected void setIsolationFilter(LoadBalancer lb, String microserviceName) {
-    final String filterName = IsolationServerListFilter.class.getName();
-    IsolationServerListFilter isolationListFilter = new 
IsolationServerListFilter();
-    isolationListFilter.setMicroserviceName(microserviceName);
-    isolationListFilter.setLoadBalancerStats(lb.getLoadBalancerStats());
-    lb.putFilter(filterName, isolationListFilter);
-  }
-
-  protected void setTransactionControlFilter(LoadBalancer lb, String 
microserviceName) {
-    final String filterName = TransactionControlFilter.class.getName();
+  protected void setTransactionControlFilter(String microserviceName) {
     String policyClsName = 
Configuration.INSTANCE.getFlowsplitFilterPolicy(microserviceName);
-    if (policyClsName.isEmpty()) {
-      return;
-    }
-    try {
-      Class<?> policyCls = Class.forName(policyClsName);
-      if (!TransactionControlFilter.class.isAssignableFrom(policyCls)) {
-        String errMsg = String.format(
-            "Define instance filter %s in yaml, but not extends abstract class 
TransactionControlFilter.",
-            policyClsName);
-        LOGGER.error(errMsg);
-        throw new Error(errMsg);
-      }
-      TransactionControlFilter transactionControlFilter = 
(TransactionControlFilter) policyCls.newInstance();
-      transactionControlFilter.setLoadBalancerStats(lb.getLoadBalancerStats());
-      transactionControlFilter.setMicroserviceName(microserviceName);
-      lb.putFilter(filterName, transactionControlFilter);
-    } catch (Throwable e) {
-      String errMsg = "Fail to create instance of class: " + policyClsName;
-      LOGGER.error(errMsg);
-      throw new Error(errMsg, e);
+    if (!policyClsName.isEmpty()) {
+      LOGGER.error(Configuration.TRANSACTIONCONTROL_POLICY_KEY_PATTERN + " is 
not supported anymore." +
+          "You can change this class to SPI, and filters will be loaded by 
SPI.");
     }
   }
 
   private void send(Invocation invocation, AsyncResponse asyncResp, final 
LoadBalancer chosenLB) throws Exception {
     long time = System.currentTimeMillis();
-    CseServer server = (CseServer) chosenLB.chooseServer(invocation);
+    ServiceCombServer server = (ServiceCombServer) 
chosenLB.chooseServer(invocation);
     if (null == server) {
       
asyncResp.consumerFail(ExceptionUtils.lbAddressNotFound(invocation.getMicroserviceName(),
           invocation.getMicroserviceVersionRule(),
@@ -269,10 +237,10 @@ public void 
onExecutionFailed(ExecutionContext<Invocation> context, Throwable fi
       public Observable<Response> call(Server s) {
         return Observable.create(f -> {
           try {
-            ((CseServer) s).setLastVisitTime(time);
+            ((ServiceCombServer) s).setLastVisitTime(time);
             chosenLB.getLoadBalancerStats().incrementNumRequests(s);
             invocation.setHandlerIndex(currentHandler); // for retry
-            invocation.setEndpoint(((CseServer) s).getEndpoint());
+            invocation.setEndpoint(((ServiceCombServer) s).getEndpoint());
             invocation.next(resp -> {
               if (isFailedResponse(resp)) {
                 LOGGER.error("service {}, call error, msg is {}, server is {} 
",
@@ -280,11 +248,11 @@ public void 
onExecutionFailed(ExecutionContext<Invocation> context, Throwable fi
                     ((Throwable) resp.getResult()).getMessage(),
                     s);
                 
chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-                ((CseServer) s).incrementContinuousFailureCount();
+                ((ServiceCombServer) s).incrementContinuousFailureCount();
                 f.onError(resp.getResult());
               } else {
                 
chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(s);
-                ((CseServer) s).clearContinuousFailure();
+                ((ServiceCombServer) s).clearContinuousFailure();
                 chosenLB.getLoadBalancerStats().noteResponseTime(s,
                     (System.currentTimeMillis() - time));
                 f.onNext(resp);
@@ -326,55 +294,28 @@ protected LoadBalancer getOrCreateLoadBalancer(Invocation 
invocation) {
         invocation.getMicroserviceName(),
         invocation.getMicroserviceVersionRule());
 
-    LoadBalancer loadBalancer = 
loadBalancerMap.computeIfAbsent(serversVersionedCache.name(), name -> {
-      return createLoadBalancer(invocation.getMicroserviceName(), name);
+    LoadBalancerCreator loadBalancerCreator = 
loadBalancerMap.computeIfAbsent(serversVersionedCache.name(), name -> {
+      return createLoadBalancerCreator(invocation.getMicroserviceName());
     });
-    LOGGER.debug("invocation {} use loadBalancer {}.",
-        invocation.getMicroserviceQualifiedName(),
-        loadBalancer.getName());
-
-    loadBalancer.setServerList(serversVersionedCache.data());
-    return loadBalancer;
+    loadBalancerCreator.setServerList(serversVersionedCache.data());
+    // help users to deal with incompatible changes.
+    setTransactionControlFilter(invocation.getMicroserviceName());
+    loadServerListFilters();
+    return loadBalancerCreator.createLoadBalancer(invocation);
   }
 
-  private LoadBalancer createLoadBalancer(String microserviceName, String 
loadBalancerName) {
+  private LoadBalancerCreator createLoadBalancerCreator(String 
microserviceName) {
     IRule rule = ExtensionsManager.createLoadBalancerRule(microserviceName);
-    LoadBalancer lb = new LoadBalancer(loadBalancerName, rule, 
microserviceName);
-
-    // we can change this implementation to ExtensionsManager in the future.
-    loadServerListFilters(lb);
-    // tow lines below is for compatibility, will remove in future
-    setIsolationFilter(lb, microserviceName);
-    setTransactionControlFilter(lb, microserviceName);
-
-    LOGGER.info("create loadBalancer, microserviceName={}, 
loadBalancerName={}.", microserviceName, loadBalancerName);
-    return lb;
+    LoadBalancerCreator creator = new LoadBalancerCreator(rule, 
microserviceName);
+    return creator;
   }
 
-  private void loadServerListFilters(LoadBalancer lb) {
+  private void loadServerListFilters() {
     String filterNames = Configuration.getStringProperty(null, 
Configuration.SERVER_LIST_FILTERS);
     if (!StringUtils.isEmpty(filterNames)) {
-      for (String filter : filterNames.split(",")) {
-        loadFilter(filter, lb);
-      }
-    }
-  }
-
-  private void loadFilter(String filter, LoadBalancer lb) {
-    String className = Configuration.getStringProperty(null,
-        String.format(Configuration.SERVER_LIST_FILTER_CLASS_HOLDER, filter));
-    if (!StringUtils.isEmpty(className)) {
-      try {
-        Class<?> filterClass = Class.forName(className, true, 
Thread.currentThread().getContextClassLoader());
-        if (ServerListFilterExt.class.isAssignableFrom(filterClass)) {
-          ServerListFilterExt ext = (ServerListFilterExt) 
filterClass.newInstance();
-          ext.setName(filter);
-          ext.setLoadBalancer(lb);
-          lb.putFilter(filter, ext);
-        }
-      } catch (InstantiationException | IllegalAccessException | 
ClassNotFoundException e) {
-        LOGGER.warn("Unable to load filter class: " + className);
-      }
+      LOGGER.error("Server list implementation changed to SPI. Configuration " 
+ Configuration.SERVER_LIST_FILTERS +
+          " is not used any more. For ServiceComb defined filters, you do not 
need config and can "
+          + "remove this configuration safely. If you define your own filter, 
need to change it to SPI to make it work.");
     }
   }
 
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 8ff78539f..2b41f0698 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
@@ -17,29 +17,31 @@
 
 package org.apache.servicecomb.loadbalance;
 
+import java.util.List;
+
 import org.apache.servicecomb.core.Invocation;
 
 import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.ServerListFilter;
 
 /**
- * 通过实现这个接口实现ServerListFilter扩展
+ *  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 extends ServerListFilter<Server> {
-  default void setName(String name) {
-
+public interface ServerListFilterExt {
+  public default int getOrder() {
+    return 0;
   }
 
-  default void setLoadBalancer(LoadBalancer lb) {
-
+  public default boolean enabled() {
+    return true;
   }
 
-  /**
-   * Server list filter should be stateless. Since invocation has state 
information, you can't use it for next invocation.
-   * Please implement stateful filters very carefully.
-   */
-  default void setInvocation(Invocation invocation) {
-
+  public default void setLoadBalancer(LoadBalancer loadBalancer) {
   }
+
+  public List<Server> getFilteredListOfServers(List<Server> servers, 
Invocation invocation);
 }
diff --git 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/CseServer.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
similarity index 81%
rename from 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/CseServer.java
rename to 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
index 120e6dc9b..e914f9a1c 100644
--- 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/CseServer.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
@@ -31,7 +31,7 @@
  * LB模块不提供服务器状态监测,这块功能是由注册中心进行处理的。
  *
  */
-public class CseServer extends Server {
+public class ServiceCombServer extends Server {
   private final Endpoint endpoint;
 
   // 所属服务实例
@@ -52,12 +52,17 @@ public void setLastVisitTime(long lastVisitTime) {
     this.lastVisitTime = lastVisitTime;
   }
 
-  public CseServer(Transport transport, CacheEndpoint cacheEndpoint) {
+  public ServiceCombServer(Transport transport, CacheEndpoint cacheEndpoint) {
     super(null);
 
     endpoint = new Endpoint(transport, cacheEndpoint.getEndpoint(), 
cacheEndpoint.getInstance());
     instance = cacheEndpoint.getInstance();
 
+    // 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);
   }
@@ -94,8 +99,8 @@ public int getCountinuousFailureCount() {
   }
 
   public boolean equals(Object o) {
-    if (o instanceof CseServer) {
-      return this.getHost().equals(((CseServer) o).getHost());
+    if (o instanceof ServiceCombServer) {
+      return this.getHost().equals(((ServiceCombServer) o).getHost());
     } else {
       return false;
     }
diff --git 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/IsolationServerListFilter.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/IsolationServerListFilter.java
index 91724d9fd..23c8e8413 100644
--- 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/IsolationServerListFilter.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/IsolationServerListFilter.java
@@ -20,17 +20,19 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.foundation.common.event.AlarmEvent.Type;
 import org.apache.servicecomb.foundation.common.event.EventManager;
 import org.apache.servicecomb.loadbalance.Configuration;
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.LoadBalancer;
 import org.apache.servicecomb.loadbalance.ServerListFilterExt;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import org.apache.servicecomb.loadbalance.event.IsolationServerEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.eventbus.EventBus;
-import com.netflix.loadbalancer.LoadBalancerStats;
+import com.netflix.config.DynamicPropertyFactory;
 import com.netflix.loadbalancer.Server;
 import com.netflix.loadbalancer.ServerStats;
 
@@ -40,8 +42,6 @@
 
   private static final double PERCENT = 100;
 
-  private String microserviceName;
-
   private int errorThresholdPercentage;
 
   private long singleTestTime;
@@ -50,29 +50,29 @@
 
   private int continuousFailureThreshold;
 
-  private LoadBalancerStats stats;
+  private LoadBalancer loadBalancer;
 
   public EventBus eventBus = EventManager.getEventBus();
 
-  public void setLoadBalancerStats(LoadBalancerStats stats) {
-    this.stats = stats;
-  }
-
-  public LoadBalancerStats getLoadBalancerStats() {
-    return stats;
+  @Override
+  public int getOrder() {
+    return 100;
   }
 
-  public String getMicroserviceName() {
-    return microserviceName;
+  @Override
+  public boolean enabled() {
+    return DynamicPropertyFactory.getInstance()
+        
.getBooleanProperty("servicecomb.loadbalance.filter.isolation.enabled", 
true).get();
   }
 
-  public void setMicroserviceName(String microserviceName) {
-    this.microserviceName = microserviceName;
+  @Override
+  public void setLoadBalancer(LoadBalancer loadBalancer) {
+    this.loadBalancer = loadBalancer;
   }
 
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> servers) {
-    if (!Configuration.INSTANCE.isIsolationFilterOpen(microserviceName)) {
+  public List<Server> getFilteredListOfServers(List<Server> servers, 
Invocation invocation) {
+    if 
(!Configuration.INSTANCE.isIsolationFilterOpen(this.loadBalancer.getMicroServiceName()))
 {
       return servers;
     }
 
@@ -86,15 +86,17 @@ public void setMicroserviceName(String microserviceName) {
   }
 
   private void updateSettings() {
-    errorThresholdPercentage = 
Configuration.INSTANCE.getErrorThresholdPercentage(microserviceName);
-    singleTestTime = 
Configuration.INSTANCE.getSingleTestTime(microserviceName);
-    enableRequestThreshold = 
Configuration.INSTANCE.getEnableRequestThreshold(microserviceName);
-    continuousFailureThreshold = 
Configuration.INSTANCE.getContinuousFailureThreshold(microserviceName);
+    errorThresholdPercentage = Configuration.INSTANCE
+        .getErrorThresholdPercentage(this.loadBalancer.getMicroServiceName());
+    singleTestTime = 
Configuration.INSTANCE.getSingleTestTime(this.loadBalancer.getMicroServiceName());
+    enableRequestThreshold = 
Configuration.INSTANCE.getEnableRequestThreshold(this.loadBalancer.getMicroServiceName());
+    continuousFailureThreshold = Configuration.INSTANCE
+        
.getContinuousFailureThreshold(this.loadBalancer.getMicroServiceName());
   }
 
   private boolean allowVisit(Server server) {
     updateSettings();
-    ServerStats serverStats = stats.getSingleServerStat(server);
+    ServerStats serverStats = 
this.loadBalancer.getLoadBalancerStats().getSingleServerStat(server);
     long totalRequest = serverStats.getTotalRequestsCount();
     long failureRequest = serverStats.getSuccessiveConnectionFailureCount();
     int currentCountinuousFailureCount = 0;
@@ -105,7 +107,7 @@ private boolean allowVisit(Server server) {
 
     if (continuousFailureThreshold > 0) {
       // continuousFailureThreshold has higher priority to decide the result
-      currentCountinuousFailureCount = ((CseServer) 
server).getCountinuousFailureCount();
+      currentCountinuousFailureCount = ((ServiceCombServer) 
server).getCountinuousFailureCount();
       if (currentCountinuousFailureCount < continuousFailureThreshold) {
         return true;
       }
@@ -117,22 +119,24 @@ private boolean allowVisit(Server server) {
       }
     }
 
-    if ((System.currentTimeMillis() - ((CseServer) server).getLastVisitTime()) 
> singleTestTime) {
+    if ((System.currentTimeMillis() - ((ServiceCombServer) 
server).getLastVisitTime()) > singleTestTime) {
       LOGGER.info("The Service {}'s instance {} has been break, will give a 
single test opportunity.",
-          microserviceName,
+          this.loadBalancer.getMicroServiceName(),
           server);
-      eventBus.post(new IsolationServerEvent(microserviceName, totalRequest, 
currentCountinuousFailureCount,
+      eventBus.post(new 
IsolationServerEvent(this.loadBalancer.getMicroServiceName(), totalRequest,
+          currentCountinuousFailureCount,
           currentErrorThresholdPercentage,
           continuousFailureThreshold, errorThresholdPercentage, 
enableRequestThreshold,
           singleTestTime, Type.CLOSE));
       return true;
     }
 
-    LOGGER.warn("The Service {}'s instance {} has been break!", 
microserviceName, server);
-    eventBus.post(new IsolationServerEvent(microserviceName, totalRequest, 
currentCountinuousFailureCount,
-        currentErrorThresholdPercentage,
-        continuousFailureThreshold, errorThresholdPercentage, 
enableRequestThreshold,
-        singleTestTime, Type.OPEN));
+    LOGGER.warn("The Service {}'s instance {} has been break!", 
this.loadBalancer.getMicroServiceName(), server);
+    eventBus.post(
+        new IsolationServerEvent(this.loadBalancer.getMicroServiceName(), 
totalRequest, currentCountinuousFailureCount,
+            currentErrorThresholdPercentage,
+            continuousFailureThreshold, errorThresholdPercentage, 
enableRequestThreshold,
+            singleTestTime, Type.OPEN));
     return false;
   }
 }
diff --git 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/CseServerDiscoveryFilter.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ServerDiscoveryFilter.java
similarity index 83%
rename from 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/CseServerDiscoveryFilter.java
rename to 
handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ServerDiscoveryFilter.java
index ac93cf910..3f9591552 100644
--- 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/CseServerDiscoveryFilter.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ServerDiscoveryFilter.java
@@ -20,14 +20,14 @@
 import org.apache.servicecomb.core.CseContext;
 import org.apache.servicecomb.core.Transport;
 import org.apache.servicecomb.core.filter.EndpointDiscoveryFilter;
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import 
org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import org.apache.servicecomb.serviceregistry.cache.CacheEndpoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class CseServerDiscoveryFilter extends EndpointDiscoveryFilter {
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(CseServerDiscoveryFilter.class);
+public class ServerDiscoveryFilter extends EndpointDiscoveryFilter {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(ServerDiscoveryFilter.class);
 
   @Override
   protected Object createEndpoint(String transportName, String endpoint, 
MicroserviceInstance instance) {
@@ -37,6 +37,6 @@ protected Object createEndpoint(String transportName, String 
endpoint, Microserv
       return null;
     }
 
-    return new CseServer(transport, new CacheEndpoint(endpoint, instance));
+    return new ServiceCombServer(transport, new CacheEndpoint(endpoint, 
instance));
   }
 }
diff --git 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/SimpleTransactionControlFilter.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/SimpleTransactionControlFilter.java
index cbaac9769..b48a38bcc 100644
--- 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/SimpleTransactionControlFilter.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/SimpleTransactionControlFilter.java
@@ -22,9 +22,11 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.loadbalance.Configuration;
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 
+import com.netflix.config.DynamicPropertyFactory;
 import com.netflix.loadbalancer.Server;
 
 /**
@@ -34,23 +36,36 @@
 public class SimpleTransactionControlFilter extends TransactionControlFilter {
 
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> servers) {
+  public boolean enabled() {
+    return DynamicPropertyFactory.getInstance()
+        .getBooleanProperty("servicecomb.loadbalance.filter.simple.enabled", 
true).get();
+  }
+
+  @Override
+  public int getOrder() {
+    return 200;
+  }
+
+  @Override
+  public List<Server> getFilteredListOfServers(List<Server> servers, 
Invocation invocation) {
     List<Server> filteredServers = new ArrayList<>();
     Map<String, String> filterOptions =
-        
Configuration.INSTANCE.getFlowsplitFilterOptions(this.microserviceName);
+        
Configuration.INSTANCE.getFlowsplitFilterOptions(this.loadBalancer.getMicroServiceName());
     for (Server server : servers) {
-      if (allowVisit((CseServer) server, filterOptions)) {
+      if (allowVisit(server, filterOptions)) {
         filteredServers.add(server);
       }
     }
     return filteredServers;
   }
 
-  protected boolean allowVisit(CseServer server, Map<String, String> 
filterOptions) {
-    Map<String, String> propertiesMap = server.getInstance().getProperties();
-    for (Entry<String, String> entry : filterOptions.entrySet()) {
-      if (!entry.getValue().equals(propertiesMap.get(entry.getKey()))) {
-        return false;
+  protected boolean allowVisit(Server server, Map<String, String> 
filterOptions) {
+    if(server instanceof ServiceCombServer) {
+      Map<String, String> propertiesMap = 
((ServiceCombServer)server).getInstance().getProperties();
+      for (Entry<String, String> entry : filterOptions.entrySet()) {
+        if (!entry.getValue().equals(propertiesMap.get(entry.getKey()))) {
+          return false;
+        }
       }
     }
     return true;
diff --git 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/TransactionControlFilter.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/TransactionControlFilter.java
index 2b51f760b..24bc98f08 100644
--- 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/TransactionControlFilter.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/TransactionControlFilter.java
@@ -17,24 +17,16 @@
 
 package org.apache.servicecomb.loadbalance.filter;
 
+import org.apache.servicecomb.loadbalance.LoadBalancer;
 import org.apache.servicecomb.loadbalance.ServerListFilterExt;
 
 import com.netflix.loadbalancer.LoadBalancerStats;
 
 public abstract class TransactionControlFilter implements ServerListFilterExt {
-  private LoadBalancerStats stats;
+  protected LoadBalancer loadBalancer;
 
-  protected String microserviceName;
-
-  public void setMicroserviceName(String microserviceName) {
-    this.microserviceName = microserviceName;
-  }
-
-  public void setLoadBalancerStats(LoadBalancerStats stats) {
-    this.stats = stats;
-  }
-
-  public LoadBalancerStats getLoadBalancerStats() {
-    return stats;
+  @Override
+  public void setLoadBalancer(LoadBalancer loadBalancer) {
+    this.loadBalancer = loadBalancer;
   }
 }
diff --git 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareServerListFilterExt.java
 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareServerListFilterExt.java
index b43af7d12..28012d70b 100644
--- 
a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareServerListFilterExt.java
+++ 
b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareServerListFilterExt.java
@@ -20,33 +20,53 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.loadbalance.LoadBalancer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import org.apache.servicecomb.loadbalance.ServerListFilterExt;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
 import 
org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 
+import com.netflix.config.DynamicPropertyFactory;
 import com.netflix.loadbalancer.Server;
 
 public class ZoneAwareServerListFilterExt implements ServerListFilterExt {
+  private LoadBalancer loadBalancer;
 
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> list) {
+  public boolean enabled() {
+    return DynamicPropertyFactory.getInstance()
+        
.getBooleanProperty("servicecomb.loadbalance.filter.zoneaware.enabled", 
true).get();
+  }
+
+  @Override
+  public void setLoadBalancer(LoadBalancer loadBalancer) {
+    this.loadBalancer = loadBalancer;
+  }
+
+  @Override
+  public int getOrder() {
+    return 300;
+  }
+
+  @Override
+  public List<Server> getFilteredListOfServers(List<Server> list, Invocation 
invocation) {
     List<Server> result = new ArrayList<>();
     MicroserviceInstance myself = RegistryUtils.getMicroserviceInstance();
     boolean find = false;
     for (Server server : list) {
-      CseServer cseServer = (CseServer) server;
-      if (regionAndAZMatch(myself, cseServer.getInstance())) {
-        result.add(cseServer);
+      ServiceCombServer serviceCombServer = (ServiceCombServer) server;
+      if (regionAndAZMatch(myself, serviceCombServer.getInstance())) {
+        result.add(serviceCombServer);
         find = true;
       }
     }
 
     if (!find) {
       for (Server server : list) {
-        CseServer cseServer = (CseServer) server;
-        if (regionMatch(myself, cseServer.getInstance())) {
-          result.add(cseServer);
+        ServiceCombServer serviceCombServer = (ServiceCombServer) server;
+        if (regionMatch(myself, serviceCombServer.getInstance())) {
+          result.add(serviceCombServer);
           find = true;
         }
       }
diff --git 
a/handlers/handler-loadbalance/src/main/resources/META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt
 
b/handlers/handler-loadbalance/src/main/resources/META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt
new file mode 100644
index 000000000..3c830cacf
--- /dev/null
+++ 
b/handlers/handler-loadbalance/src/main/resources/META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt
@@ -0,0 +1,3 @@
+org.apache.servicecomb.loadbalance.filter.IsolationServerListFilter
+org.apache.servicecomb.loadbalance.filter.SimpleTransactionControlFilter
+org.apache.servicecomb.loadbalance.filter.ZoneAwareServerListFilterExt
\ No newline at end of file
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 f7919e9a2..ed0878988 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
@@ -29,18 +29,11 @@
  *
  */
 public class MyServerListFilterExt implements ServerListFilterExt {
-  private Invocation invocation;
-
   @Override
-  public List<Server> getFilteredListOfServers(List<Server> serverList) {
+  public List<Server> getFilteredListOfServers(List<Server> serverList, 
Invocation invocation) {
     if (invocation.getAppId().equals("test")) {
       return new ArrayList<>();
     }
     return serverList;
   }
-
-  @Override
-  public void setInvocation(Invocation invocation) {
-    this.invocation = invocation;
-  }
 }
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
new file mode 100644
index 000000000..7fb24d3c2
--- /dev/null
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
@@ -0,0 +1,206 @@
+/*
+ * 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 org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
+import org.apache.servicecomb.loadbalance.filter.IsolationServerListFilter;
+import 
org.apache.servicecomb.loadbalance.filter.SimpleTransactionControlFilter;
+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;
+import mockit.Injectable;
+import mockit.Mocked;
+
+public class TestLoadBalanceCreator {
+  @Test
+  public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable 
Invocation invocation) {
+    // 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);
+    servers.add(server);
+    servers.add(server2);
+    LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "test");
+
+    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) {
+          if (server.getHost().equals("host1")) {
+            continue;
+          }
+          filteredServers.add(server);
+        }
+        return filteredServers;
+      }
+    });
+    lbCreator.setFilters(filters);
+
+    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
+    Server s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+  }
+
+  @Test
+  public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation 
invocation) {
+    // Robin components implementations require getReachableServers & 
getServerList have the same size, we add a test case for this.
+    RandomRule rule = new RandomRule();
+    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);
+    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) {
+          if (server.getHost().equals("host1")) {
+            continue;
+          }
+          filteredServers.add(server);
+        }
+        return filteredServers;
+      }
+    });
+    lbCreator.setFilters(filters);
+    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
+    Server s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+  }
+
+  @Test
+  public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Mocked 
ServiceCombServer server,
+      @Mocked ServiceCombServer server2, @Injectable Invocation invocation) {
+    // Robin components implementations require getReachableServers & 
getServerList have the same size, we add a test case for this.
+    WeightedResponseTimeRule rule = new WeightedResponseTimeRule();
+    LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
+    List<Server> servers = new ArrayList<>();
+
+    new Expectations() {
+      {
+        server.getHost();
+        result = "host1";
+
+        server2.isReadyToServe();
+        result = true;
+        server2.isAlive();
+        result = true;
+        server2.getHost();
+        result = "host2";
+      }
+    };
+
+    servers.add(server);
+    servers.add(server2);
+    lbCreator.setServerList(servers);
+    SimpleTransactionControlFilter simpleFilter = new 
SimpleTransactionControlFilter();
+    IsolationServerListFilter isolationFilter = new 
IsolationServerListFilter();
+    List<ServerListFilterExt> filters = new ArrayList<>();
+    filters.add(simpleFilter);
+    filters.add(isolationFilter);
+    filters.add(new ServerListFilterExt() {
+      @Override
+      public List<Server> getFilteredListOfServers(List<Server> serverList, 
Invocation invocation) {
+        List<Server> filteredServers = new ArrayList<>();
+        for (Server server : servers) {
+          if (server.getHost().equals("host1")) {
+            continue;
+          }
+          filteredServers.add(server);
+        }
+        return filteredServers;
+      }
+    });
+    lbCreator.setFilters(filters);
+    LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
+    Server s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+  }
+
+  @Test
+  public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation 
invocation) {
+    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);
+    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);
+
+    long time = Deencapsulation.getField(rule, "lastAccessedTime");
+    Deencapsulation.setField(rule, "lastAccessedTime", time - 1000 * 10);
+    
ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.sessionTimeoutInSeconds",
 9);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server, s);
+
+    
ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.successiveFailedTimes",
 5);
+    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
+    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
+    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
+    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
+    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
+    s = lb.chooseServer("test");
+    Assert.assertEquals(server2, s);
+  }
+}
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 f48a5d368..b03b911d0 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
@@ -22,9 +22,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
-import org.apache.servicecomb.loadbalance.filter.IsolationServerListFilter;
-import 
org.apache.servicecomb.loadbalance.filter.SimpleTransactionControlFilter;
 import org.apache.servicecomb.loadbalance.filter.TransactionControlFilter;
 import org.junit.Assert;
 import org.junit.Test;
@@ -32,32 +29,18 @@
 
 import com.netflix.loadbalancer.AbstractLoadBalancer.ServerGroup;
 import com.netflix.loadbalancer.IRule;
-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;
-import mockit.Mocked;
 
 public class TestLoadBalancer {
   private IRule rule = Mockito.mock(IRule.class);
 
-  private LoadBalancer loadBalancer = new LoadBalancer("loadBalancerName", 
rule, "test");
-
-  @Test
-  public void name() {
-    Assert.assertEquals("loadBalancerName", loadBalancer.getName());
-  }
-
   @SuppressWarnings("deprecation")
   @Test
   public void testLoadBalancerFullOperationWithoutException() {
     List<Server> newServers = new ArrayList<>();
     Server server = Mockito.mock(Server.class);
     newServers.add(server);
-
+    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
     loadBalancer.setServerList(newServers);
     loadBalancer.chooseServer();
 
@@ -80,7 +63,8 @@ public void testAddServerException() {
     Server server = Mockito.mock(Server.class);
 
     newServers.add(server);
-
+    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
+    loadBalancer.setServerList(newServers);
     try {
 
       loadBalancer.addServers(newServers);
@@ -101,7 +85,8 @@ public void testServerListException() {
     Server server = Mockito.mock(Server.class);
 
     newServers.add(server);
-
+    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
+    loadBalancer.setServerList(newServers);
     try {
 
       loadBalancer.getServerList(ServerGroup.ALL);
@@ -122,7 +107,8 @@ public void testMarkServerDownException() {
     Server server = Mockito.mock(Server.class);
 
     newServers.add(server);
-
+    LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
+    loadBalancer.setServerList(newServers);
     try {
 
       loadBalancer.markServerDown(server);
@@ -136,181 +122,15 @@ public void testMarkServerDownException() {
     Assert.assertFalse(status);
   }
 
-  @Test
-  public void testFilter() {
-    Assert.assertEquals(0, loadBalancer.getFilterSize());
-
-    TransactionControlFilter filter = new SimpleTransactionControlFilter();
-    loadBalancer.putFilter("test", filter);
-    Assert.assertEquals(1, loadBalancer.getFilterSize());
-  }
-
   @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);
-
     TransactionControlFilter filter = 
Mockito.mock(TransactionControlFilter.class);
-    Mockito.when(filter.getFilteredListOfServers(servers)).thenReturn(servers);
+    Mockito.when(filter.getFilteredListOfServers(servers, 
null)).thenReturn(servers);
     Assert.assertEquals(servers, loadBalancer.getAllServers());
   }
-
-  @Test
-  public void testLoadBalanceWithRoundRobinRuleAndFilter() {
-    // Robin components implementations require getReachableServers & 
getServerList have the same size, we add a test case for this.
-    RoundRobinRule rule = new RoundRobinRule();
-    LoadBalancer lb = new LoadBalancer("lb1", 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);
-    servers.add(server);
-    servers.add(server2);
-    lb.setServerList(servers);
-    lb.putFilter("testFiler", new ServerListFilterExt() {
-      @Override
-      public List<Server> getFilteredListOfServers(List<Server> servers) {
-        List<Server> filteredServers = new ArrayList<>();
-        for (Server server : servers) {
-          if (server.getHost().equals("host1")) {
-            continue;
-          }
-          filteredServers.add(server);
-        }
-        return filteredServers;
-      }
-    });
-    Server s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-  }
-
-  @Test
-  public void testLoadBalanceWithRandomRuleAndFilter() {
-    // Robin components implementations require getReachableServers & 
getServerList have the same size, we add a test case for this.
-    RandomRule rule = new RandomRule();
-    LoadBalancer lb = new LoadBalancer("lb1", 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);
-    servers.add(server);
-    servers.add(server2);
-    lb.setServerList(servers);
-    lb.putFilter("testFiler", new ServerListFilterExt() {
-      @Override
-      public List<Server> getFilteredListOfServers(List<Server> servers) {
-        List<Server> filteredServers = new ArrayList<>();
-        for (Server server : servers) {
-          if (server.getHost().equals("host1")) {
-            continue;
-          }
-          filteredServers.add(server);
-        }
-        return filteredServers;
-      }
-    });
-    Server s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-  }
-
-  @Test
-  public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Mocked 
CseServer server,
-      @Mocked CseServer server2) {
-    // Robin components implementations require getReachableServers & 
getServerList have the same size, we add a test case for this.
-    WeightedResponseTimeRule rule = new WeightedResponseTimeRule();
-    LoadBalancer lb = new LoadBalancer("lb1", rule, "service");
-    List<Server> servers = new ArrayList<>();
-
-    new Expectations() {
-      {
-        server.getHost();
-        result = "host1";
-
-        server2.isReadyToServe();
-        result = true;
-        server2.isAlive();
-        result = true;
-        server2.getHost();
-        result = "host2";
-      }
-    };
-
-    servers.add(server);
-    servers.add(server2);
-    lb.setServerList(servers);
-    SimpleTransactionControlFilter simpleFilter = new 
SimpleTransactionControlFilter();
-    simpleFilter.setMicroserviceName("service");
-    IsolationServerListFilter isolationFilter = new 
IsolationServerListFilter();
-    isolationFilter.setMicroserviceName("service");
-    lb.putFilter("simpleFilter", simpleFilter);
-    lb.putFilter("isolationFilter", isolationFilter);
-    lb.putFilter("testFiler", new ServerListFilterExt() {
-      @Override
-      public List<Server> getFilteredListOfServers(List<Server> servers) {
-        List<Server> filteredServers = new ArrayList<>();
-        for (Server server : servers) {
-          if (server.getHost().equals("host1")) {
-            continue;
-          }
-          filteredServers.add(server);
-        }
-        return filteredServers;
-      }
-    });
-    Server s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-  }
-
-  @Test
-  public void testLoadBalanceWithSessionSticknessRule() {
-    SessionStickinessRule rule = new SessionStickinessRule();
-    LoadBalancer lb = new LoadBalancer("lb1", rule, "service");
-    Assert.assertEquals(lb.getMicroServiceName(), "service");
-    Assert.assertEquals("service", Deencapsulation.getField(rule, 
"microserviceName"));
-
-    List<Server> servers = new ArrayList<>();
-    Server server = new Server("host1", 80);
-    server.setAlive(true);
-    Server server2 = new Server("host2", 80);
-    server2.setAlive(true);
-    servers.add(server);
-    servers.add(server2);
-    lb.setServerList(servers);
-
-    Server s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-
-    long time = Deencapsulation.getField(rule, "lastAccessedTime");
-    Deencapsulation.setField(rule, "lastAccessedTime", time - 1000 * 10);
-    
ArchaiusUtils.setProperty("servicecomb.loadbalance.service.SessionStickinessRule.sessionTimeoutInSeconds",
 9);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server, s);
-
-    
ArchaiusUtils.setProperty("servicecomb.loadbalance.service.SessionStickinessRule.successiveFailedTimes",
 5);
-    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-    lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
-    s = lb.chooseServer("test");
-    Assert.assertEquals(server2, s);
-  }
 }
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 2080233ab..1de1d6d06 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
@@ -57,6 +57,7 @@
 
 import com.netflix.config.DynamicPropertyFactory;
 import com.netflix.loadbalancer.IRule;
+import com.netflix.loadbalancer.LoadBalancerStats;
 import com.netflix.loadbalancer.Server;
 
 import mockit.Deencapsulation;
@@ -77,9 +78,9 @@
 
   LoadbalanceHandler handler;
 
-  Map<String, LoadBalancer> loadBalancerMap;
+  Map<String, LoadBalancerCreator> loadBalancerMap;
 
-  private LoadBalancer loadBalancer = new LoadBalancer("loadBalancerName", 
rule, "test");
+  private LoadBalancerCreator loadBalancerCreator = new 
LoadBalancerCreator(rule, "test");
 
   @Injectable
   Invocation invocation;
@@ -170,152 +171,6 @@ public void teardown() {
     ArchaiusUtils.resetConfig();
   }
 
-  @Test
-  public void handleClearLoadBalancer() throws Exception {
-    new MockUp<LoadbalanceHandler>(handler) {
-      @Mock
-      LoadBalancer getOrCreateLoadBalancer(Invocation invocation) {
-        return loadBalancer;
-      }
-
-      @Mock
-      void send(Invocation invocation, AsyncResponse asyncResp, final 
LoadBalancer choosenLB) throws Exception {
-      }
-    };
-
-    loadBalancerMap.put("old", loadBalancer);
-    Deencapsulation.setField(handler, "policy", "init");
-    handler.handle(invocation, ar -> {
-    });
-
-    Assert.assertThat(loadBalancerMap.values(), Matchers.empty());
-  }
-
-  @Test
-  public void handleSendNotRetry() throws Exception {
-    new MockUp<LoadbalanceHandler>(handler) {
-      @Mock
-      LoadBalancer getOrCreateLoadBalancer(Invocation invocation) {
-        return loadBalancer;
-      }
-
-      @Mock
-      void send(Invocation invocation, AsyncResponse asyncResp, final 
LoadBalancer choosenLB) throws Exception {
-        results.add("sendNotRetry");
-      }
-    };
-
-    handler.handle(invocation, ar -> {
-    });
-
-    Assert.assertThat(results, Matchers.contains("sendNotRetry"));
-  }
-
-  @Test
-  public void handleSendWithRetry() throws Exception {
-    new MockUp<LoadbalanceHandler>(handler) {
-      @Mock
-      LoadBalancer getOrCreateLoadBalancer(Invocation invocation) {
-        return loadBalancer;
-      }
-
-      @Mock
-      void sendWithRetry(Invocation invocation, AsyncResponse asyncResp, final 
LoadBalancer choosenLB)
-          throws Exception {
-        results.add("sendWithRetry");
-      }
-    };
-
-    new MockUp<Configuration>(Configuration.INSTANCE) {
-      @Mock
-      boolean isRetryEnabled(String microservice) {
-        return true;
-      }
-    };
-
-    handler.handle(invocation, ar -> {
-    });
-
-    Assert.assertThat(results, Matchers.contains("sendWithRetry"));
-  }
-
-  @Test
-  public void testSetIsolationFilter() {
-    Invocation invocation = Mockito.mock(Invocation.class);
-    Mockito.when(invocation.getMicroserviceName()).thenReturn("test");
-    LoadbalanceHandler lbHandler = new LoadbalanceHandler();
-    LoadBalancer myLB = new LoadBalancer("loadBalancerName", rule, "test");
-    lbHandler.setIsolationFilter(myLB, "abc");
-    Assert.assertEquals(1, myLB.getFilterSize());
-
-    Mockito.when(invocation.getMicroserviceName()).thenReturn("abc");
-    myLB = new LoadBalancer("loadBalancerName", rule, "test");
-    lbHandler.setIsolationFilter(myLB, "abc");
-    myLB.setInvocation(invocation);
-
-    Assert.assertEquals(1, myLB.getFilterSize());
-    Map<String, ServerListFilterExt> filters = Deencapsulation.getField(myLB, 
"filters");
-    List<Server> servers = new ArrayList<>();
-    servers.add(new Server(null));
-    Assert.assertEquals(servers.size(),
-        
filters.get("org.apache.servicecomb.loadbalance.filter.IsolationServerListFilter")
-            .getFilteredListOfServers(servers)
-            .size());
-  }
-
-  @Test
-  public void setTransactionControlFilter_NoPolicy() {
-    new MockUp<Configuration>(Configuration.INSTANCE) {
-      @Mock
-      String getFlowsplitFilterPolicy(String microservice) {
-        return "";
-      }
-    };
-
-    handler.setTransactionControlFilter(loadBalancer, microserviceName);
-    Assert.assertEquals(0, loadBalancer.getFilterSize());
-  }
-
-  @Test
-  public void setTransactionControlFilter_InvalidPolicy() {
-    
ArchaiusUtils.setProperty("servicecomb.loadbalance.ms.transactionControl.policy",
 "InvalidPolicy");
-
-    expectedException.expect(Error.class);
-    expectedException.expectMessage(Matchers.is("Fail to create instance of 
class: InvalidPolicy"));
-
-    handler.setTransactionControlFilter(loadBalancer, microserviceName);
-    Assert.assertEquals(0, loadBalancer.getFilterSize());
-  }
-
-  @Test
-  public void setTransactionControlFilter_PolicyNotAssignable() {
-    new MockUp<Configuration>(Configuration.INSTANCE) {
-      @Mock
-      String getFlowsplitFilterPolicy(String microservice) {
-        return String.class.getName();
-      }
-    };
-
-    expectedException.expect(Error.class);
-    expectedException.expectMessage(Matchers.is("Fail to create instance of 
class: java.lang.String"));
-
-    handler.setTransactionControlFilter(loadBalancer, microserviceName);
-    Assert.assertEquals(0, loadBalancer.getFilterSize());
-  }
-
-  @Test
-  public void setTransactionControlFilter_Normal() {
-    new MockUp<Configuration>(Configuration.INSTANCE) {
-      @Mock
-      String getFlowsplitFilterPolicy(String microservice) {
-        return SimpleTransactionControlFilter.class.getName();
-      }
-    };
-
-    handler.setTransactionControlFilter(loadBalancer, microserviceName);
-    Assert.assertEquals(1, loadBalancer.getFilterSize());
-  }
-
   @Test
   public void getOrCreateLoadBalancer() throws Exception {
     LoadbalanceHandler handler = new LoadbalanceHandler();
@@ -341,13 +196,11 @@ public void getOrCreateLoadBalancer() throws Exception {
 
     LoadBalancer lb = handler.getOrCreateLoadBalancer(invocation);
 
-    Assert.assertEquals(2, lb.getFilterSize());
-    Assert.assertEquals("instanceCache/rest", lb.getName());
     Assert.assertEquals("[rest://localhost:8080]", 
Deencapsulation.getField(lb, "serverList").toString());
   }
 
   @Test
-  public void send_noEndPoint() {
+  public void send_noEndPoint(@Injectable LoadBalancer loadBalancer) {
     new Expectations(loadBalancer) {
       {
         loadBalancer.chooseServer(invocation);
@@ -367,9 +220,10 @@ public void send_noEndPoint() {
   }
 
   @Test
-  public void send_failed() {
+  public void send_failed(@Injectable LoadBalancer loadBalancer) {
     CacheEndpoint cacheEndpoint = new CacheEndpoint("rest://localhost:8080", 
null);
-    CseServer server = new CseServer(restTransport, cacheEndpoint);
+    ServiceCombServer server = new ServiceCombServer(restTransport, 
cacheEndpoint);
+    LoadBalancerStats stats = new LoadBalancerStats("test");
     new MockUp<System>() {
       @Mock
       long currentTimeMillis() {
@@ -380,6 +234,8 @@ long currentTimeMillis() {
       {
         loadBalancer.chooseServer(invocation);
         result = server;
+        loadBalancer.getLoadBalancerStats();
+        result = stats;
       }
     };
     int continuousFailureCount = server.getCountinuousFailureCount();
@@ -400,9 +256,10 @@ long currentTimeMillis() {
   }
 
   @Test
-  public void send_success() {
+  public void send_success(@Injectable LoadBalancer loadBalancer) {
     CacheEndpoint cacheEndpoint = new CacheEndpoint("rest://localhost:8080", 
null);
-    CseServer server = new CseServer(restTransport, cacheEndpoint);
+    ServiceCombServer server = new ServiceCombServer(restTransport, 
cacheEndpoint);
+    LoadBalancerStats stats = new LoadBalancerStats("test");
     new MockUp<System>() {
       @Mock
       long currentTimeMillis() {
@@ -413,6 +270,8 @@ long currentTimeMillis() {
       {
         loadBalancer.chooseServer(invocation);
         result = server;
+        loadBalancer.getLoadBalancerStats();
+        result = stats;
       }
     };
     server.incrementContinuousFailureCount();
@@ -432,7 +291,7 @@ long currentTimeMillis() {
   }
 
   @Test
-  public void sendWithRetry() {
+  public void sendWithRetry(@Injectable LoadBalancer loadBalancer) {
     Holder<String> result = new Holder<>();
     Deencapsulation.invoke(handler, "sendWithRetry", invocation, 
(AsyncResponse) resp -> {
       result.value = resp.getResult();
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestCseServer.java
 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServer.java
similarity index 88%
rename from 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestCseServer.java
rename to 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServer.java
index 6b7010e5b..b8898da1a 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestCseServer.java
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServer.java
@@ -30,11 +30,11 @@
  *
  *
  */
-public class TestCseServer {
+public class TestServiceCombServer {
 
   private Transport transport = Mockito.mock(Transport.class);
 
-  private CseServer cs = new CseServer(transport, new CacheEndpoint("abcd", 
null));
+  private ServiceCombServer cs = new ServiceCombServer(transport, new 
CacheEndpoint("abcd", null));
 
   @Test
   public void testCseServerObj() {
@@ -51,10 +51,10 @@ public void testGetEndpoint() {
   public void testEqualsMethod() {
     Assert.assertFalse(cs.equals((Object) "abcd"));
 
-    CseServer other = new CseServer(transport, new CacheEndpoint("1234", 
null));
+    ServiceCombServer other = new ServiceCombServer(transport, new 
CacheEndpoint("1234", null));
     Assert.assertFalse(cs.equals(other));
 
-    other = new CseServer(transport, new CacheEndpoint("abcd", null));
+    other = new ServiceCombServer(transport, new CacheEndpoint("abcd", null));
     Assert.assertTrue(cs.equals(other));
   }
 
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 420f6fdbf..3a5777acb 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
@@ -44,7 +44,7 @@ public void testRuleFullOperation() {
 
     LoadBalancer mockedLb = mock(LoadBalancer.class);
     Transport transport = mock(Transport.class);
-    CseServer mockedServer = new CseServer(transport, new 
CacheEndpoint("rest:127.0.0.1:8889", null));
+    ServiceCombServer mockedServer = new ServiceCombServer(transport, new 
CacheEndpoint("rest:127.0.0.1:8889", null));
     Object key = Mockito.mock(Object.class);
     LoadBalancerStats stats = mock(LoadBalancerStats.class);
     Mockito.when(mockedLb.getLoadBalancerStats()).thenReturn(stats);
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestIsolationServerListFilter.java
 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestIsolationServerListFilter.java
index 9343f70a8..3da9aa648 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestIsolationServerListFilter.java
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestIsolationServerListFilter.java
@@ -25,7 +25,8 @@
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.foundation.common.event.AlarmEvent;
 import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.LoadBalancer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Assert;
@@ -37,6 +38,7 @@
 import com.google.common.eventbus.Subscribe;
 import com.netflix.config.DynamicPropertyFactory;
 import com.netflix.loadbalancer.LoadBalancerStats;
+import com.netflix.loadbalancer.RandomRule;
 import com.netflix.loadbalancer.Server;
 
 public class TestIsolationServerListFilter {
@@ -89,39 +91,25 @@ public void tearDown() throws Exception {
     
configuration.clearProperty("servicecomb.loadbalance.isolation.continuousFailureThreshold");
   }
 
-  @Test
-  public void testSetLoadBalancerStats() {
-    isolationServerListFilter.setLoadBalancerStats(loadBalancerStats);
-    Assert.assertNotNull(isolationServerListFilter.getLoadBalancerStats());
-    Assert.assertEquals(loadBalancerStats, 
isolationServerListFilter.getLoadBalancerStats());
-  }
-
-  @Test
-  public void testSetMicroserviceName() {
-    isolationServerListFilter.setMicroserviceName("microserviceName");
-    Assert.assertNotNull(isolationServerListFilter.getMicroserviceName());
-    Assert.assertEquals("microserviceName", 
isolationServerListFilter.getMicroserviceName());
-  }
-
   @Test
   public void testGetFilteredListOfServers() {
     Invocation invocation = Mockito.mock(Invocation.class);
-    CseServer testServer = Mockito.mock(CseServer.class);
+    ServiceCombServer testServer = Mockito.mock(ServiceCombServer.class);
     
Mockito.when(invocation.getMicroserviceName()).thenReturn("microserviceName");
     
Mockito.when(testServer.getLastVisitTime()).thenReturn(System.currentTimeMillis());
 
     List<Server> serverList = new ArrayList<>();
     serverList.add(testServer);
-    isolationServerListFilter.setLoadBalancerStats(loadBalancerStats);
-    isolationServerListFilter.setInvocation(invocation);
-    List<Server> returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList);
+    LoadBalancer loadBalancer = new LoadBalancer(new RandomRule(), 
"microserviceName", loadBalancerStats);
+    isolationServerListFilter.setLoadBalancer(loadBalancer);
+    List<Server> returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList, null);
     Assert.assertEquals(returnedServerList.size(), 1);
 
     loadBalancerStats.incrementNumRequests(testServer);
     loadBalancerStats.incrementNumRequests(testServer);
     loadBalancerStats.incrementNumRequests(testServer);
     loadBalancerStats.incrementSuccessiveConnectionFailureCount(testServer);
-    returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList);
+    returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList, null);
     Assert.assertEquals(returnedServerList.size(), 0);
   }
 
@@ -131,7 +119,7 @@ public void 
testGetFilteredListOfServersOnContinuousFailureReachesThreshold() {
         
.addProperty("servicecomb.loadbalance.isolation.continuousFailureThreshold",
             "3");
     Invocation invocation = Mockito.mock(Invocation.class);
-    CseServer testServer = Mockito.mock(CseServer.class);
+    ServiceCombServer testServer = Mockito.mock(ServiceCombServer.class);
     
Mockito.when(invocation.getMicroserviceName()).thenReturn("microserviceName");
     Mockito.when(testServer.getCountinuousFailureCount()).thenReturn(3);
     
Mockito.when(testServer.getLastVisitTime()).thenReturn(System.currentTimeMillis());
@@ -142,9 +130,9 @@ public void 
testGetFilteredListOfServersOnContinuousFailureReachesThreshold() {
 
     List<Server> serverList = new ArrayList<>();
     serverList.add(testServer);
-    isolationServerListFilter.setLoadBalancerStats(loadBalancerStats);
-    isolationServerListFilter.setInvocation(invocation);
-    List<Server> returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList);
+    LoadBalancer loadBalancer = new LoadBalancer(new RandomRule(), 
"microserviceName", loadBalancerStats);
+    isolationServerListFilter.setLoadBalancer(loadBalancer);
+    List<Server> returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList, null);
     Assert.assertEquals(0, returnedServerList.size());
     Assert.assertEquals(1, taskList.size());
   }
@@ -155,7 +143,7 @@ public void 
testGetFilteredListOfServersOnContinuousFailureIsBelowThreshold() {
         
.addProperty("servicecomb.loadbalance.isolation.continuousFailureThreshold",
             "3");
     Invocation invocation = Mockito.mock(Invocation.class);
-    CseServer testServer = Mockito.mock(CseServer.class);
+    ServiceCombServer testServer = Mockito.mock(ServiceCombServer.class);
     
Mockito.when(invocation.getMicroserviceName()).thenReturn("microserviceName");
     Mockito.when(testServer.getCountinuousFailureCount()).thenReturn(2);
     
Mockito.when(testServer.getLastVisitTime()).thenReturn(System.currentTimeMillis());
@@ -166,9 +154,9 @@ public void 
testGetFilteredListOfServersOnContinuousFailureIsBelowThreshold() {
 
     List<Server> serverList = new ArrayList<>();
     serverList.add(testServer);
-    isolationServerListFilter.setLoadBalancerStats(loadBalancerStats);
-    isolationServerListFilter.setInvocation(invocation);
-    List<Server> returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList);
+    LoadBalancer loadBalancer = new LoadBalancer(new RandomRule(), 
"microserviceName", loadBalancerStats);
+    isolationServerListFilter.setLoadBalancer(loadBalancer);
+    List<Server> returnedServerList = 
isolationServerListFilter.getFilteredListOfServers(serverList, null);
     Assert.assertEquals(1, returnedServerList.size());
   }
 }
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestCseServerDiscoveryFilter.java
 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
similarity index 85%
rename from 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestCseServerDiscoveryFilter.java
rename to 
handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
index 247c44663..3a5e8b959 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestCseServerDiscoveryFilter.java
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
@@ -21,7 +21,7 @@
 import org.apache.servicecomb.core.CseContext;
 import org.apache.servicecomb.core.Transport;
 import org.apache.servicecomb.core.transport.TransportManager;
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import 
org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import org.junit.After;
 import org.junit.Assert;
@@ -31,8 +31,8 @@
 import mockit.Expectations;
 import mockit.Mocked;
 
-public class TestCseServerDiscoveryFilter {
-  CseServerDiscoveryFilter filter = new CseServerDiscoveryFilter();
+public class TestServerDiscoveryFilter {
+  ServerDiscoveryFilter filter = new ServerDiscoveryFilter();
 
   @Mocked
   TransportManager transportManager;
@@ -59,7 +59,7 @@ public void createEndpoint_TransportNotExist() {
       }
     };
 
-    CseServer server = (CseServer) filter.createEndpoint(Const.RESTFUL, null, 
null);
+    ServiceCombServer server = (ServiceCombServer) 
filter.createEndpoint(Const.RESTFUL, null, null);
     Assert.assertNull(server);
   }
 
@@ -73,7 +73,7 @@ public void createEndpointNormal() {
     };
     MicroserviceInstance instance = new MicroserviceInstance();
 
-    CseServer server = (CseServer) filter.createEndpoint(Const.RESTFUL, 
"rest://localhost:8080", instance);
+    ServiceCombServer server = (ServiceCombServer) 
filter.createEndpoint(Const.RESTFUL, "rest://localhost:8080", instance);
     Assert.assertSame(instance, server.getInstance());
     Assert.assertSame(trasport, server.getEndpoint().getTransport());
     Assert.assertEquals("rest://localhost:8080", 
server.getEndpoint().getEndpoint());
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestSimpleTransactionControlFilter.java
 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestSimpleTransactionControlFilter.java
index f2a46691f..5189b049a 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestSimpleTransactionControlFilter.java
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestSimpleTransactionControlFilter.java
@@ -25,7 +25,8 @@
 import org.apache.commons.configuration.AbstractConfiguration;
 import org.apache.commons.configuration.BaseConfiguration;
 import org.apache.servicecomb.core.Invocation;
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.LoadBalancer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import 
org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import org.junit.Assert;
 import org.junit.Before;
@@ -33,13 +34,14 @@
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import com.netflix.loadbalancer.RandomRule;
 import com.netflix.loadbalancer.Server;
 
 public class TestSimpleTransactionControlFilter {
 
   private SimpleTransactionControlFilter filter;
 
-  private CseServer server;
+  private ServiceCombServer server;
 
   @BeforeClass
   public static void beforeCls() {
@@ -52,12 +54,14 @@ public static void beforeCls() {
   @Before
   public void setUp() {
     filter = new SimpleTransactionControlFilter();
+    LoadBalancer loadBalancer = new LoadBalancer(new RandomRule(), 
"microserviceName", null);
+    filter.setLoadBalancer(loadBalancer);
     Map<String, String> properties = new HashMap<>();
     properties.put("tag0", "value0");
     properties.put("tag1", "value1");
     MicroserviceInstance instance = new MicroserviceInstance();
     instance.setProperties(properties);
-    server = Mockito.mock(CseServer.class);
+    server = Mockito.mock(ServiceCombServer.class);
     Mockito.when(server.getInstance()).thenReturn(instance);
   }
 
@@ -80,11 +84,10 @@ public void testAllowVisit() {
   @Test
   public void testGetFilteredListOfServers() {
     Invocation invocation = Mockito.mock(Invocation.class);
-    filter.setInvocation(invocation);
 
     List<Server> servers = new ArrayList<>();
     servers.add(server);
-    List<Server> filteredServers = filter.getFilteredListOfServers(servers);
+    List<Server> filteredServers = filter.getFilteredListOfServers(servers, 
null);
     Assert.assertEquals(1, filteredServers.size());
   }
 }
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareServerListFilterExt.java
 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareServerListFilterExt.java
index 9c61bb463..e3e587bc2 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareServerListFilterExt.java
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareServerListFilterExt.java
@@ -19,7 +19,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.servicecomb.loadbalance.CseServer;
+import org.apache.servicecomb.loadbalance.ServiceCombServer;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
 import org.apache.servicecomb.serviceregistry.api.registry.DataCenterInfo;
 import 
org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
@@ -73,7 +73,7 @@ public void testZoneAwareServerListFilterExt(@Mocked 
RegistryUtils registryUtils
     };
     ZoneAwareServerListFilterExt filter = new ZoneAwareServerListFilterExt();
     List<Server> servers = new ArrayList<>();
-    CseServer noneMatchServer = new MockUp<CseServer>() {
+    ServiceCombServer noneMatchServer = new MockUp<ServiceCombServer>() {
       @Mock
       public String toString() {
         return "noneMatchServer";
@@ -89,7 +89,7 @@ public MicroserviceInstance getInstance() {
         return noneMatchInstance;
       }
     }.getMockInstance();
-    CseServer regionMatchregionMatchServer = new MockUp<CseServer>() {
+    ServiceCombServer regionMatchregionMatchServer = new 
MockUp<ServiceCombServer>() {
       @Mock
       public String toString() {
         return "regionMatchregionMatchServer";
@@ -106,7 +106,7 @@ public MicroserviceInstance getInstance() {
       }
     }.getMockInstance();
 
-    CseServer allmatchServer = new MockUp<CseServer>() {
+    ServiceCombServer allmatchServer = new MockUp<ServiceCombServer>() {
       @Mock
       public String toString() {
         return "allmatchServer";
@@ -124,17 +124,17 @@ public MicroserviceInstance getInstance() {
     }.getMockInstance();
 
     servers.add(noneMatchServer);
-    List<Server> result = filter.getFilteredListOfServers(servers);
+    List<Server> result = filter.getFilteredListOfServers(servers, null);
     Assert.assertEquals(result.size(), 1);
     Assert.assertEquals(result.get(0), noneMatchServer);
 
     servers.add(regionMatchregionMatchServer);
-    result = filter.getFilteredListOfServers(servers);
+    result = filter.getFilteredListOfServers(servers, null);
     Assert.assertEquals(result.size(), 1);
     Assert.assertEquals(result.get(0), regionMatchregionMatchServer);
 
     servers.add(allmatchServer);
-    result = filter.getFilteredListOfServers(servers);
+    result = filter.getFilteredListOfServers(servers, null);
     Assert.assertEquals(result.size(), 1);
     Assert.assertEquals(result.get(0), allmatchServer);
   }


 

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


> refactor loadbalance filters logic to support invocation based filter
> ---------------------------------------------------------------------
>
>                 Key: SCB-706
>                 URL: https://issues.apache.org/jira/browse/SCB-706
>             Project: Apache ServiceComb
>          Issue Type: Improvement
>            Reporter: liubao
>            Assignee: liubao
>            Priority: Major
>
> Why we do this?
>  # When implement invocation based filter, e.g. darklaunch deployment, we 
> need to filter servers based on invocation parameters. But now, we create a 
> Loadbalaner instance for each service, and Robin filter interface can not 
> pass Invocation to it. Before refactor, we doing this by ThreadLocal and 
> cache Invocation, and use in filter implementation. This is error prone and 
> users can't handle this complixity
>  # We have other improvements, e.g. SCB-700, we can do server status check, 
> and add a filter a choose from active servers. We need to consider filter 
> orders and other feature, current implementation not satisfy this.
>  # We want to make loadbalance code handy by remove some compatible fixes. 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to