You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2018/09/03 05:09:04 UTC

[incubator-dubbo] branch dev-metadata updated: Refactor tag router

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

liujun pushed a commit to branch dev-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/dev-metadata by this push:
     new 72e47d9  Refactor tag router
72e47d9 is described below

commit 72e47d9de4a645801f9eb6fd7f88ed75dd3ee180
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon Sep 3 13:08:41 2018 +0800

    Refactor tag router
---
 .../dubbo/rpc/cluster/router/AbstractRouter.java   |  19 +++
 .../rpc/cluster/router/AbstractRouterRule.java     |  11 +-
 .../cluster/router/condition/ConditionRouter.java  |  16 +-
 .../condition/config/ConfigConditionRouter.java    |  41 +++--
 .../config/{ => model}/ConditionRouterRule.java    |  13 +-
 .../config/{ => model}/ConditionRuleParser.java    |  30 +++-
 .../rpc/cluster/router/group/GroupRouter.java      |  22 ++-
 .../cluster/router/group/GroupRouterFactory.java   |   2 +-
 .../router/group/model/GroupRouterRule.java        |   1 +
 .../dubbo/rpc/cluster/router/tag/TagRouter.java    | 109 -------------
 .../rpc/cluster/router/tag/TagRouterFactory.java   |  32 ----
 .../rpc/cluster/router/tag/TagRouterTest.java      | 169 ---------------------
 12 files changed, 110 insertions(+), 355 deletions(-)

diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
index 95abaca..9dd1740 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
@@ -30,6 +30,8 @@ import java.util.Map;
  * TODO Extract more code here if necessary
  */
 public abstract class AbstractRouter implements Router {
+    protected int priority;
+    protected boolean force;
     protected RouterChain routerChain;
 
     @Override
@@ -51,4 +53,21 @@ public abstract class AbstractRouter implements Router {
     public void setRouterChain(RouterChain routerChain) {
         this.routerChain = routerChain;
     }
+
+    @Override
+    public boolean isForce() {
+        return force;
+    }
+
+    public void setForce(boolean force) {
+        this.force = force;
+    }
+
+    public int getPriority() {
+        return priority;
+    }
+
+    public void setPriority(int priority) {
+        this.priority = priority;
+    }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java
index 4a0c6e4..6dbbc95 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java
@@ -20,17 +20,18 @@ package org.apache.dubbo.rpc.cluster.router;
  * TODO Extract more code here if necessary
  */
 public abstract class AbstractRouterRule {
-    private String ruleBody;
+    private String rawRule;
     private boolean runtime = false;
     private boolean force = false;
     private boolean valid = true;
 
-    public String getRuleBody() {
-        return ruleBody;
+
+    public String getRawRule() {
+        return rawRule;
     }
 
-    public void setRuleBody(String ruleBody) {
-        this.ruleBody = ruleBody;
+    public void setRawRule(String rawRule) {
+        this.rawRule = rawRule;
     }
 
     public boolean isRuntime() {
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
index d596b6c..de46808 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
@@ -50,13 +50,12 @@ public class ConditionRouter extends AbstractRouter implements Comparable<Router
     private static final Logger logger = LoggerFactory.getLogger(ConditionRouter.class);
     protected static Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)");
     protected URL url;
-    protected int priority;
-    protected boolean force;
     protected Map<String, MatchPair> whenCondition;
     protected Map<String, MatchPair> thenCondition;
 
-    protected ConditionRouter() {
-
+    public ConditionRouter(String rule, boolean force) {
+        this.force = force;
+        this.init(rule);
     }
 
     public ConditionRouter(URL url) {
@@ -66,7 +65,7 @@ public class ConditionRouter extends AbstractRouter implements Comparable<Router
         init(url.getParameterAndDecoded(Constants.RULE_KEY));
     }
 
-    protected void init(String rule) {
+    public void init(String rule) {
         try {
             if (rule == null || rule.trim().length() == 0) {
                 throw new IllegalArgumentException("Illegal route rule!");
@@ -211,11 +210,6 @@ public class ConditionRouter extends AbstractRouter implements Comparable<Router
     }
 
     @Override
-    public boolean isForce() {
-        return force;
-    }
-
-    @Override
     public URL getUrl() {
         return url;
     }
@@ -226,7 +220,7 @@ public class ConditionRouter extends AbstractRouter implements Comparable<Router
             return 1;
         }
         ConditionRouter c = (ConditionRouter) o;
-        return this.priority == c.priority ? url.toFullString().compareTo(c.url.toFullString()) : (this.priority > c.priority ? 1 : -1);
+        return this.priority > c.priority ? 1 : -1;
     }
 
     boolean matchWhen(URL url, Invocation invocation) {
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
index 98c442e..1d950aa 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
@@ -27,10 +27,14 @@ import org.apache.dubbo.config.dynamic.DynamicConfiguration;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.cluster.RouterChain;
+import org.apache.dubbo.rpc.cluster.Router;
+import org.apache.dubbo.rpc.cluster.router.AbstractRouter;
 import org.apache.dubbo.rpc.cluster.router.TreeNode;
 import org.apache.dubbo.rpc.cluster.router.condition.ConditionRouter;
+import org.apache.dubbo.rpc.cluster.router.condition.config.model.ConditionRouterRule;
+import org.apache.dubbo.rpc.cluster.router.condition.config.model.ConditionRuleParser;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -38,11 +42,12 @@ import java.util.Map;
 /**
  * TODO only support one router rule =>, it will be inconvenient if we want to add more than one rules.
  */
-public class ConfigConditionRouter extends ConditionRouter implements ConfigurationListener {
+public class ConfigConditionRouter extends AbstractRouter implements ConfigurationListener {
     public static final String NAME = "CONFIG_CONDITION_OUTER";
     private static final Logger logger = LoggerFactory.getLogger(ConfigConditionRouter.class);
     private DynamicConfiguration configuration;
     private ConditionRouterRule routerRule;
+    private List<ConditionRouter> conditionRouters;
 
     public ConfigConditionRouter(DynamicConfiguration configuration) {
         this.configuration = configuration;
@@ -52,7 +57,7 @@ public class ConfigConditionRouter extends ConditionRouter implements Configurat
             String app = configuration.getUrl().getParameter(Constants.APPLICATION_KEY);
             String rawRule = configuration.getConfig(app + Constants.ROUTERS_SUFFIX, "dubbo", this);
             routerRule = ConditionRuleParser.parse(rawRule);
-            init(routerRule.getRuleBody());
+            init();
         } catch (Exception e) {
             throw new IllegalStateException(e.getMessage(), e);
         }
@@ -63,7 +68,7 @@ public class ConfigConditionRouter extends ConditionRouter implements Configurat
         String rawRule = event.getNewValue();
         try {
             routerRule = ConditionRuleParser.parse(rawRule);
-            init(routerRule.getRuleBody());
+            init();
             routerChain.notifyRuleChanged();
         } catch (Exception e) {
             logger.error(e);
@@ -71,6 +76,19 @@ public class ConfigConditionRouter extends ConditionRouter implements Configurat
         }
     }
 
+    private void init() {
+        if (routerRule == null || !routerRule.isValid()) {
+            return;
+        }
+
+        conditionRouters = new ArrayList<>();
+        routerRule.getConditions().forEach(condition -> {
+            // All sub rules have the same force, runtime value.
+            ConditionRouter subRouter = new ConditionRouter(condition, routerRule.isForce());
+            conditionRouters.add(subRouter);
+        });
+    }
+
     @Override
     public <T> Map<String, List<Invoker<T>>> preRoute(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
         Map<String, List<Invoker<T>>> map = new HashMap<>();
@@ -85,17 +103,15 @@ public class ConfigConditionRouter extends ConditionRouter implements Configurat
         }
 
         // only one branch, always use the failover key
-        map.put(TreeNode.FAILOVER_KEY, route(invokers, url, invocation));
+        for (Router router : conditionRouters) {
+            invokers = router.route(invokers, url, invocation);
+        }
+        map.put(TreeNode.FAILOVER_KEY, invokers);
 
         return map;
     }
 
     @Override
-    public void setRouterChain(RouterChain routerChain) {
-
-    }
-
-    @Override
     public boolean isRuntime() {
         return routerRule != null && routerRule.isValid() && routerRule.isRuntime();
     }
@@ -114,4 +130,9 @@ public class ConfigConditionRouter extends ConditionRouter implements Configurat
     public String getName() {
         return NAME;
     }
+
+    @Override
+    public int compareTo(Router o) {
+        return 0;
+    }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConditionRouterRule.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/model/ConditionRouterRule.java
similarity index 73%
rename from dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConditionRouterRule.java
rename to dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/model/ConditionRouterRule.java
index 1cf3d73..0c426a3 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConditionRouterRule.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/model/ConditionRouterRule.java
@@ -14,13 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.rpc.cluster.router.condition.config;
+package org.apache.dubbo.rpc.cluster.router.condition.config.model;
 
 import org.apache.dubbo.rpc.cluster.router.AbstractRouterRule;
 
+import java.util.List;
+
 /**
  *
  */
 public class ConditionRouterRule extends AbstractRouterRule {
+    private String scope;
+    private List<String> conditions;
+
+    public List<String> getConditions() {
+        return conditions;
+    }
 
+    public void setConditions(List<String> conditions) {
+        this.conditions = conditions;
+    }
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConditionRuleParser.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/model/ConditionRuleParser.java
similarity index 56%
rename from dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConditionRuleParser.java
rename to dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/model/ConditionRuleParser.java
index f9bc49f..859b7f3 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConditionRuleParser.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/model/ConditionRuleParser.java
@@ -14,18 +14,38 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.rpc.cluster.router.condition.config;
+package org.apache.dubbo.rpc.cluster.router.condition.config.model;
+
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
 
 /**
+ * %YAML1.2
  *
+ * scope: application
+ * runtime: true
+ * force: false
+ * conditions:
+ *   - >
+ *     method!=sayHello =>
+ *   - >
+ *     ip=127.0.0.1
+ *     =>
+ *     1.1.1.1
  */
 public class ConditionRuleParser {
 
     public static ConditionRouterRule parse(String rawRule) {
-        ConditionRouterRule conditionRouterRule = new ConditionRouterRule();
-        conditionRouterRule.setRuleBody("method!=sayHello => ");
-        conditionRouterRule.setValid(true);
-        return conditionRouterRule;
+        Constructor constructor = new Constructor(ConditionRouterRule.class);
+
+        Yaml yaml = new Yaml(constructor);
+        ConditionRouterRule rule = yaml.load(rawRule);
+        rule.setRawRule(rawRule);
+        if (CollectionUtils.isEmpty(rule.getConditions())) {
+            rule.setValid(false);
+        }
+        return rule;
     }
 
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouter.java
index 724992d..d655e30 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouter.java
@@ -47,12 +47,10 @@ import java.util.stream.Collectors;
  *
  */
 public class GroupRouter extends AbstractRouter implements Comparable<Router>, ConfigurationListener {
-    public static final String NAME = "GROUP_ROUTER";
+    public static final String NAME = "TAG_ROUTER";
     private static final Logger logger = LoggerFactory.getLogger(GroupRouter.class);
-    private static final String GROUPRULE_DATAID = "global.routers";
-    private static final String ROUTE_GROUP = "route.group";
-    private static final String ROUTE_FAILOVER = "route.failover";
-    private int priority;
+    private static final String TAGRULE_DATAID = "global.tag.rules";
+    private static final String FAILOVER_TAG = "tag.failover";
     private URL url;
     private DynamicConfiguration configuration;
     private GroupRouterRule groupRouterRule;
@@ -69,7 +67,7 @@ public class GroupRouter extends AbstractRouter implements Comparable<Router>, C
     }
 
     public void init() {
-        String rawRule = configuration.getConfig(GROUPRULE_DATAID, "dubbo", this);
+        String rawRule = configuration.getConfig(TAGRULE_DATAID, "dubbo", this);
         this.groupRouterRule = GroupRuleParser.parse(rawRule);
     }
 
@@ -92,18 +90,18 @@ public class GroupRouter extends AbstractRouter implements Comparable<Router>, C
             return invokers;
         }
         List<Invoker<T>> result = invokers;
-        String routeGroup = StringUtils.isEmpty(invocation.getAttachment(ROUTE_GROUP)) ? url.getParameter(ROUTE_GROUP) : invocation.getAttachment(ROUTE_GROUP);
+        String routeGroup = StringUtils.isEmpty(invocation.getAttachment(Constants.REQUEST_TAG_KEY)) ? url.getParameter(Constants.TAG_KEY) : invocation.getAttachment(Constants.REQUEST_TAG_KEY);
         if (StringUtils.isNotEmpty(routeGroup)) {
             String providerApp = invokers.get(0).getUrl().getParameter(Constants.APPLICATION_KEY);
             List<String> addresses = groupRouterRule.filter(routeGroup, providerApp);
             if (CollectionUtils.isNotEmpty(addresses)) {
                 result = filterInvoker(invokers, invoker -> addressMatches(invoker.getUrl(), addresses));
             } else {
-                result = filterInvoker(invokers, invoker -> invoker.getUrl().getParameter(ROUTE_GROUP).equals(routeGroup));
+                result = filterInvoker(invokers, invoker -> invoker.getUrl().getParameter(Constants.TAG_KEY).equals(routeGroup));
             }
         }
-        if (StringUtils.isEmpty(routeGroup) || (CollectionUtils.isEmpty(result) && url.getParameter(ROUTE_FAILOVER, true))) {
-            result = filterInvoker(invokers, invoker -> StringUtils.isEmpty(invoker.getUrl().getParameter(ROUTE_GROUP)));
+        if (StringUtils.isEmpty(routeGroup) || (CollectionUtils.isEmpty(result) && url.getParameter(FAILOVER_TAG, true))) {
+            result = filterInvoker(invokers, invoker -> StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY)));
         }
         return result;
     }
@@ -126,7 +124,7 @@ public class GroupRouter extends AbstractRouter implements Comparable<Router>, C
             String address = invoker.getUrl().getAddress();
             String routeGroup = groupRouterRule.getIpAppToGroup().get(providerApp + address);
             if (StringUtils.isEmpty(routeGroup)) {
-                routeGroup = invoker.getUrl().getParameter(ROUTE_GROUP);
+                routeGroup = invoker.getUrl().getParameter(Constants.TAG_KEY);
             }
             if (StringUtils.isEmpty(routeGroup)) {
                 routeGroup = TreeNode.FAILOVER_KEY;
@@ -149,7 +147,7 @@ public class GroupRouter extends AbstractRouter implements Comparable<Router>, C
     }
 
     public String getKey() {
-        return ROUTE_GROUP;
+        return Constants.TAG_KEY;
     }
 
     @Override
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouterFactory.java
index 761d02e..2da2ffe 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouterFactory.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/GroupRouterFactory.java
@@ -28,7 +28,7 @@ import org.apache.dubbo.rpc.cluster.RouterFactory;
 @Activate
 public class GroupRouterFactory implements RouterFactory {
 
-    public static final String NAME = "group";
+    public static final String NAME = "tag";
 
     @Override
     public Router getRouter(URL url) {
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/model/GroupRouterRule.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/model/GroupRouterRule.java
index d434e42..64516e6 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/model/GroupRouterRule.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/group/model/GroupRouterRule.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Map;
 
 /**
+ * %YAML1.2
  *
  */
 public class GroupRouterRule extends AbstractRouterRule {
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
deleted file mode 100644
index 38fd616..0000000
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
+++ /dev/null
@@ -1,109 +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.dubbo.rpc.cluster.router.tag;
-
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.cluster.Router;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * TagRouter
- */
-public class TagRouter implements Router, Comparable<Router> {
-
-    private static final Logger logger = LoggerFactory.getLogger(TagRouter.class);
-
-    private final int priority;
-    private final URL url;
-
-    public static final URL ROUTER_URL = new URL("tag", Constants.ANYHOST_VALUE, 0, Constants.ANY_VALUE).addParameters(Constants.RUNTIME_KEY, "true");
-
-    public TagRouter(URL url) {
-        this.url = url;
-        this.priority = url.getParameter(Constants.PRIORITY_KEY, 0);
-    }
-
-    public TagRouter() {
-        this.url = ROUTER_URL;
-        this.priority = url.getParameter(Constants.PRIORITY_KEY, 0);
-    }
-
-    @Override
-    public URL getUrl() {
-        return url;
-    }
-
-    @Override
-    public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
-        // filter
-        List<Invoker<T>> result = new ArrayList<>();
-        try {
-            // Dynamic param
-            String tag = RpcContext.getContext().getAttachment(Constants.REQUEST_TAG_KEY);
-            // Tag request
-            if (!StringUtils.isEmpty(tag)) {
-                // Select tag invokers first
-                for (Invoker<T> invoker : invokers) {
-                    if (tag.equals(invoker.getUrl().getParameter(Constants.TAG_KEY))) {
-                        result.add(invoker);
-                    }
-                }
-                // If no invoker be selected, downgrade to normal invokers
-                if (result.isEmpty()) {
-                    for (Invoker<T> invoker : invokers) {
-                        if (StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY))) {
-                            result.add(invoker);
-                        }
-                    }
-                }
-            // Normal request
-            } else {
-                for (Invoker<T> invoker : invokers) {
-                    // Can't access tag invoker,only normal invoker should be selected
-                    if (StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY))) {
-                        result.add(invoker);
-                    }
-                }
-            }
-            return result;
-        } catch (Exception e) {
-            logger.error("Route by tag error,return all invokers.", e);
-        }
-        // Downgrade to all invokers
-        return invokers;
-    }
-
-    @Override
-    public int compareTo(Router o) {
-        if (o == null || o.getClass() != TagRouter.class) {
-            return 1;
-        }
-        TagRouter c = (TagRouter) o;
-        return this.priority == c.priority ? url.toFullString().compareTo(c.url.toFullString()) : (this.priority > c.priority ? 1 : -1);
-    }
-}
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
deleted file mode 100644
index 05ad427..0000000
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
+++ /dev/null
@@ -1,32 +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.dubbo.rpc.cluster.router.tag;
-
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.cluster.Router;
-import org.apache.dubbo.rpc.cluster.RouterFactory;
-
-public class TagRouterFactory implements RouterFactory {
-
-    public static final String NAME = "tag";
-
-    @Override
-    public Router getRouter(URL url) {
-        return new TagRouter(url);
-    }
-}
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java
deleted file mode 100644
index 839af44..0000000
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java
+++ /dev/null
@@ -1,169 +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.dubbo.rpc.cluster.router.tag;
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.cluster.Router;
-import org.apache.dubbo.rpc.cluster.RouterFactory;
-import org.apache.dubbo.rpc.cluster.router.MockInvoker;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TagRouterTest {
-
-    private URL tagUrl = new URL("tag"
-            , Constants.ANYHOST_VALUE, 0
-            , Constants.ANY_VALUE)
-            .addParameters(
-                    Constants.RUNTIME_KEY, "true"
-            );
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() throws Exception {
-    }
-
-    @Test
-    public void testRoute_matchTag() {
-
-        RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "red");
-
-        List<Invoker<String>> invokers = new ArrayList<>();
-        Invoker<String> redInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red"));
-        Invoker<String> yellowInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow"));
-        Invoker<String> blueInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue"));
-        Invoker<String> defaultInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.4:20880/com.foo.BarService"));
-
-        invokers.add(redInvoker);
-        invokers.add(yellowInvoker);
-        invokers.add(blueInvoker);
-        invokers.add(defaultInvoker);
-
-        Router tagRouter = new TagRouterFactory().getRouter(tagUrl);
-        List<Invoker<String>> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation());
-        Assert.assertTrue(filteredInvokers.contains(redInvoker));
-        Assert.assertFalse(filteredInvokers.contains(yellowInvoker));
-        Assert.assertFalse(filteredInvokers.contains(blueInvoker));
-        Assert.assertFalse(filteredInvokers.contains(defaultInvoker));
-    }
-
-    @Test
-    public void testRoute_matchDefault() {
-
-        RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "");
-
-        List<Invoker<String>> invokers = new ArrayList<>();
-        Invoker<String> redInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red"));
-        Invoker<String> yellowInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow"));
-        Invoker<String> blueInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue"));
-        Invoker<String> defaultInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.4:20880/com.foo.BarService"));
-
-        invokers.add(redInvoker);
-        invokers.add(yellowInvoker);
-        invokers.add(blueInvoker);
-        invokers.add(defaultInvoker);
-
-        Router tagRouter = new TagRouterFactory().getRouter(tagUrl);
-        List<Invoker<String>> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation());
-        Assert.assertTrue(filteredInvokers.contains(defaultInvoker));
-        Assert.assertFalse(filteredInvokers.contains(yellowInvoker));
-        Assert.assertFalse(filteredInvokers.contains(blueInvoker));
-        Assert.assertFalse(filteredInvokers.contains(redInvoker));
-    }
-
-    @Test
-    public void testRoute_requestWithTag_shouldDowngrade() {
-
-        RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "black");
-
-        List<Invoker<String>> invokers = new ArrayList<>();
-        Invoker<String> redInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red"));
-        Invoker<String> yellowInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow"));
-        Invoker<String> blueInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue"));
-        Invoker<String> defaultInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.4:20880/com.foo.BarService"));
-
-        invokers.add(redInvoker);
-        invokers.add(yellowInvoker);
-        invokers.add(blueInvoker);
-        invokers.add(defaultInvoker);
-
-        Router tagRouter = new TagRouterFactory().getRouter(tagUrl);
-        List<Invoker<String>> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation());
-        Assert.assertTrue(filteredInvokers.contains(defaultInvoker));
-        Assert.assertFalse(filteredInvokers.contains(yellowInvoker));
-        Assert.assertFalse(filteredInvokers.contains(blueInvoker));
-        Assert.assertFalse(filteredInvokers.contains(redInvoker));
-    }
-
-    @Test
-    public void testRoute_requestWithoutTag_shouldNotDowngrade() {
-
-        RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "");
-
-        List<Invoker<String>> invokers = new ArrayList<>();
-        Invoker<String> redInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red"));
-        Invoker<String> yellowInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow"));
-        Invoker<String> blueInvoker = new MockInvoker<>(URL.valueOf(
-                "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue"));
-
-        invokers.add(redInvoker);
-        invokers.add(yellowInvoker);
-        invokers.add(blueInvoker);
-
-        Router tagRouter = new TagRouterFactory().getRouter(tagUrl);
-        List<Invoker<String>> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation());
-        Assert.assertEquals(0, filteredInvokers.size());
-    }
-
-    @Test
-    public void testRoute_createBySpi() {
-        URL zkProvider = URL.valueOf("zookeeper://10.20.3.1:20880/com.foo.BarService?router=tag");
-        String parameter = zkProvider.getParameter(Constants.ROUTER_KEY);
-        RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getExtension(parameter);
-        Router tagRouter = routerFactory.getRouter(zkProvider);
-        Assert.assertTrue(tagRouter instanceof TagRouter);
-    }
-
-}