From e8bc8489af35ed9601fb5801c20bbba372a7cb5b Mon Sep 17 00:00:00 2001
From: Joe Zou <yixian.zou@gmail.com>
Date: Wed, 24 Jun 2020 18:10:37 +0800
Subject: [PATCH] optimize router

---
 cluster/directory/base_directory.go           |  4 +-
 cluster/router/chain/chain.go                 | 30 +++++++----
 cluster/router/chain/chain_test.go            |  4 +-
 cluster/router/chan.go                        | 25 ++++++++++
 cluster/router/condition/factory.go           | 14 +++---
 cluster/router/condition/factory_test.go      | 50 +++++++++----------
 cluster/router/healthcheck/factory.go         |  6 +--
 .../router/healthcheck/health_check_route.go  |  2 +-
 cluster/router/router.go                      | 32 ++++++------
 cluster/router/tag/factory.go                 |  8 +--
 cluster/router/tag/factory_test.go            |  2 +-
 common/extension/router_factory.go            | 14 +++---
 12 files changed, 111 insertions(+), 80 deletions(-)
 create mode 100644 cluster/router/chan.go

diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go
index 0f941fdcc..7865b807a 100644
--- a/cluster/directory/base_directory.go
+++ b/cluster/directory/base_directory.go
@@ -83,14 +83,14 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) {
 		return
 	}
 
-	routers := make([]router.Router, 0, len(urls))
+	routers := make([]router.PriorityRouter, 0, len(urls))
 
 	for _, url := range urls {
 		routerKey := url.GetParam(constant.ROUTER_KEY, "")
 
 		if len(routerKey) > 0 {
 			factory := extension.GetRouterFactory(url.Protocol)
-			r, err := factory.NewRouter(url)
+			r, err := factory.NewPriorityRouter(url)
 			if err != nil {
 				logger.Errorf("Create router fail. router key: %s, url:%s, error: %+v", routerKey, url.Service(), err)
 				return
diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go
index d48a837eb..97d20ac5f 100644
--- a/cluster/router/chain/chain.go
+++ b/cluster/router/chain/chain.go
@@ -40,19 +40,21 @@ type RouterChain struct {
 	// Full list of addresses from registry, classified by method name.
 	invokers []protocol.Invoker
 	// Containing all routers, reconstruct every time 'route://' urls change.
-	routers []router.Router
+	routers []router.PriorityRouter
 	// Fixed router instances: ConfigConditionRouter, TagRouter, e.g., the rule for each instance may change but the
 	// instance will never delete or recreate.
-	builtinRouters []router.Router
+	builtinRouters []router.PriorityRouter
 
 	mutex sync.RWMutex
+
+	url common.URL
 }
 
 // Route Loop routers in RouterChain and call Route method to determine the target invokers list.
 func (c *RouterChain) Route(invoker []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
 	finalInvokers := invoker
 	l := len(c.routers)
-	rs := make([]router.Router, l, int(math.Ceil(float64(l)*1.2)))
+	rs := make([]router.PriorityRouter, l, int(math.Ceil(float64(l)*1.2)))
 	c.mutex.RLock()
 	copy(rs, c.routers)
 	c.mutex.RUnlock()
@@ -67,8 +69,8 @@ func (c *RouterChain) Route(invoker []protocol.Invoker, url *common.URL, invocat
 // New a array add builtinRouters which is not sorted in RouterChain and routers
 // Sort the array
 // Replace router array in RouterChain
-func (c *RouterChain) AddRouters(routers []router.Router) {
-	newRouters := make([]router.Router, 0, len(c.builtinRouters)+len(routers))
+func (c *RouterChain) AddRouters(routers []router.PriorityRouter) {
+	newRouters := make([]router.PriorityRouter, 0, len(c.builtinRouters)+len(routers))
 	newRouters = append(newRouters, c.builtinRouters...)
 	newRouters = append(newRouters, routers...)
 	sortRouter(newRouters)
@@ -77,6 +79,11 @@ func (c *RouterChain) AddRouters(routers []router.Router) {
 	c.routers = newRouters
 }
 
+// URL Return URL in RouterChain
+func (c *RouterChain) URL() common.URL {
+	return c.url
+}
+
 // NewRouterChain Use url to init router chain
 // Loop routerFactories and call NewRouter method
 func NewRouterChain(url *common.URL) (*RouterChain, error) {
@@ -84,9 +91,9 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) {
 	if len(routerFactories) == 0 {
 		return nil, perrors.Errorf("No routerFactory exits , create one please")
 	}
-	routers := make([]router.Router, 0, len(routerFactories))
+	routers := make([]router.PriorityRouter, 0, len(routerFactories))
 	for key, routerFactory := range routerFactories {
-		r, err := routerFactory().NewRouter(url)
+		r, err := routerFactory().NewPriorityRouter(url)
 		if r == nil || err != nil {
 			logger.Errorf("router chain build router fail! routerFactories key:%s  error:%s", key, err.Error())
 			continue
@@ -94,7 +101,7 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) {
 		routers = append(routers, r)
 	}
 
-	newRouters := make([]router.Router, len(routers))
+	newRouters := make([]router.PriorityRouter, len(routers))
 	copy(newRouters, routers)
 
 	sortRouter(newRouters)
@@ -103,17 +110,20 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) {
 		builtinRouters: routers,
 		routers:        newRouters,
 	}
+	if url != nil {
+		chain.url = *url
+	}
 
 	return chain, nil
 }
 
 // sortRouter Sort router instance by priority with stable algorithm
-func sortRouter(routers []router.Router) {
+func sortRouter(routers []router.PriorityRouter) {
 	sort.Stable(byPriority(routers))
 }
 
 // byPriority Sort by priority
-type byPriority []router.Router
+type byPriority []router.PriorityRouter
 
 func (a byPriority) Len() int           { return len(a) }
 func (a byPriority) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/cluster/router/chain/chain_test.go b/cluster/router/chain/chain_test.go
index c7a75f3d8..b4e4e1c0b 100644
--- a/cluster/router/chain/chain_test.go
+++ b/cluster/router/chain/chain_test.go
@@ -127,11 +127,11 @@ conditions:
 	url := getConditionRouteUrl("test-condition")
 	assert.NotNil(t, url)
 	factory := extension.GetRouterFactory(url.Protocol)
-	r, err := factory.NewRouter(url)
+	r, err := factory.NewPriorityRouter(url)
 	assert.Nil(t, err)
 	assert.NotNil(t, r)
 
-	routers := make([]router.Router, 0)
+	routers := make([]router.PriorityRouter, 0)
 	routers = append(routers, r)
 	chain.AddRouters(routers)
 	assert.Equal(t, 3, len(chain.routers))
diff --git a/cluster/router/chan.go b/cluster/router/chan.go
new file mode 100644
index 000000000..6904e1734
--- /dev/null
+++ b/cluster/router/chan.go
@@ -0,0 +1,25 @@
+/*
+ * 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 router
+
+// Chain
+type Chain interface {
+	router
+	// AddRouters Add routers
+	AddRouters([]PriorityRouter)
+}
diff --git a/cluster/router/condition/factory.go b/cluster/router/condition/factory.go
index 66512a138..f8d3e1301 100644
--- a/cluster/router/condition/factory.go
+++ b/cluster/router/condition/factory.go
@@ -32,28 +32,28 @@ func init() {
 // ConditionRouterFactory Condition router factory
 type ConditionRouterFactory struct{}
 
-func newConditionRouterFactory() router.RouterFactory {
+func newConditionRouterFactory() router.PriorityRouterFactory {
 	return &ConditionRouterFactory{}
 }
 
-// NewRouter Create ConditionRouterFactory by URL
-func (c *ConditionRouterFactory) NewRouter(url *common.URL) (router.Router, error) {
+// NewPriorityRouter creates ConditionRouterFactory by URL
+func (c *ConditionRouterFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) {
 	return NewConditionRouter(url)
 }
 
 // NewRouter Create FileRouterFactory by Content
-func (c *ConditionRouterFactory) NewFileRouter(content []byte) (router.Router, error) {
+func (c *ConditionRouterFactory) NewFileRouter(content []byte) (router.PriorityRouter, error) {
 	return NewFileConditionRouter(content)
 }
 
 // AppRouterFactory Application router factory
 type AppRouterFactory struct{}
 
-func newAppRouterFactory() router.RouterFactory {
+func newAppRouterFactory() router.PriorityRouterFactory {
 	return &AppRouterFactory{}
 }
 
-// NewRouter Create AppRouterFactory by URL
-func (c *AppRouterFactory) NewRouter(url *common.URL) (router.Router, error) {
+// NewPriorityRouter creates AppRouterFactory by URL
+func (c *AppRouterFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) {
 	return NewAppRouter(url)
 }
diff --git a/cluster/router/condition/factory_test.go b/cluster/router/condition/factory_test.go
index a826cafb8..d080a46cc 100644
--- a/cluster/router/condition/factory_test.go
+++ b/cluster/router/condition/factory_test.go
@@ -121,32 +121,32 @@ func (bi *MockInvoker) Destroy() {
 func TestRouteMatchWhen(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4"))
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	cUrl, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService")
 	matchWhen := router.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, true, matchWhen)
 	rule1 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
-	router1, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule1))
+	router1, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule1))
 	matchWhen1 := router1.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, true, matchWhen1)
 	rule2 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4"))
-	router2, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule2))
+	router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2))
 	matchWhen2 := router2.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, false, matchWhen2)
 	rule3 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.4 & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
-	router3, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule3))
+	router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3))
 	matchWhen3 := router3.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, true, matchWhen3)
 	rule4 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
-	router4, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule4))
+	router4, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule4))
 	matchWhen4 := router4.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, true, matchWhen4)
 	rule5 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.1 => host = 1.2.3.4"))
-	router5, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule5))
+	router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5))
 	matchWhen5 := router5.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, false, matchWhen5)
 	rule6 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.2 => host = 1.2.3.4"))
-	router6, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule6))
+	router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6))
 	matchWhen6 := router6.(*ConditionRouter).MatchWhen(&cUrl, inv)
 	assert.Equal(t, true, matchWhen6)
 }
@@ -164,12 +164,12 @@ func TestRouteMatchFilter(t *testing.T) {
 	rule4 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 10.20.3.2,10.20.3.3,10.20.3.4"))
 	rule5 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host != 10.20.3.3"))
 	rule6 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " serialization = fastjson"))
-	router1, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule1))
-	router2, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule2))
-	router3, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule3))
-	router4, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule4))
-	router5, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule5))
-	router6, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule6))
+	router1, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule1))
+	router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2))
+	router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3))
+	router4, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule4))
+	router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5))
+	router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6))
 	cUrl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
 	fileredInvokers1 := router1.Route(invokers, &cUrl, &invocation.RPCInvocation{})
 	fileredInvokers2 := router2.Route(invokers, &cUrl, &invocation.RPCInvocation{})
@@ -189,7 +189,7 @@ func TestRouteMatchFilter(t *testing.T) {
 func TestRouteMethodRoute(t *testing.T) {
 	inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{}))
 	rule := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	url, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=setFoo,getFoo,findFoo")
 	matchWhen := router.(*ConditionRouter).MatchWhen(&url, inv)
 	assert.Equal(t, true, matchWhen)
@@ -198,12 +198,12 @@ func TestRouteMethodRoute(t *testing.T) {
 	assert.Equal(t, true, matchWhen)
 	url2, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo")
 	rule2 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host!=1.1.1.1 => host = 1.2.3.4"))
-	router2, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule2))
+	router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2))
 	matchWhen = router2.(*ConditionRouter).MatchWhen(&url2, inv)
 	assert.Equal(t, false, matchWhen)
 	url3, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo")
 	rule3 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host=1.1.1.1 => host = 1.2.3.4"))
-	router3, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule3))
+	router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3))
 	matchWhen = router3.(*ConditionRouter).MatchWhen(&url3, inv)
 	assert.Equal(t, true, matchWhen)
 
@@ -216,7 +216,7 @@ func TestRouteReturnFalse(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => false"))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 0, len(fileredInvokers))
 }
@@ -228,7 +228,7 @@ func TestRouteReturnEmpty(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => "))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 0, len(fileredInvokers))
 }
@@ -244,7 +244,7 @@ func TestRouteReturnAll(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, invokers, fileredInvokers)
 }
@@ -261,7 +261,7 @@ func TestRouteHostFilter(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 2, len(fileredInvokers))
 	assert.Equal(t, invoker2, fileredInvokers[0])
@@ -280,7 +280,7 @@ func TestRouteEmptyHostFilter(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte(" => " + " host = " + localIP))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 2, len(fileredInvokers))
 	assert.Equal(t, invoker2, fileredInvokers[0])
@@ -299,7 +299,7 @@ func TestRouteFalseHostFilter(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 2, len(fileredInvokers))
 	assert.Equal(t, invoker2, fileredInvokers[0])
@@ -318,7 +318,7 @@ func TestRoutePlaceholder(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = $host"))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 2, len(fileredInvokers))
 	assert.Equal(t, invoker2, fileredInvokers[0])
@@ -337,7 +337,7 @@ func TestRouteNoForce(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4"))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrlWithNoForce(rule))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithNoForce(rule))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, invokers, fileredInvokers)
 }
@@ -354,7 +354,7 @@ func TestRouteForce(t *testing.T) {
 	inv := &invocation.RPCInvocation{}
 	rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4"))
 	curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
-	router, _ := newConditionRouterFactory().NewRouter(getRouteUrlWithForce(rule, "true"))
+	router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithForce(rule, "true"))
 	fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
 	assert.Equal(t, 0, len(fileredInvokers))
 }
diff --git a/cluster/router/healthcheck/factory.go b/cluster/router/healthcheck/factory.go
index 32d84d145..40c9dd7ab 100644
--- a/cluster/router/healthcheck/factory.go
+++ b/cluster/router/healthcheck/factory.go
@@ -33,11 +33,11 @@ type HealthCheckRouteFactory struct {
 }
 
 // newHealthCheckRouteFactory construct a new HealthCheckRouteFactory
-func newHealthCheckRouteFactory() router.RouterFactory {
+func newHealthCheckRouteFactory() router.PriorityRouterFactory {
 	return &HealthCheckRouteFactory{}
 }
 
-// NewRouter construct a new NewHealthCheckRouter via url
-func (f *HealthCheckRouteFactory) NewRouter(url *common.URL) (router.Router, error) {
+// NewPriorityRouter construct a new NewHealthCheckRouter via url
+func (f *HealthCheckRouteFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) {
 	return NewHealthCheckRouter(url)
 }
diff --git a/cluster/router/healthcheck/health_check_route.go b/cluster/router/healthcheck/health_check_route.go
index 1ddc9ccb1..ee42e47e3 100644
--- a/cluster/router/healthcheck/health_check_route.go
+++ b/cluster/router/healthcheck/health_check_route.go
@@ -38,7 +38,7 @@ type HealthCheckRouter struct {
 }
 
 // NewHealthCheckRouter construct an HealthCheckRouter via url
-func NewHealthCheckRouter(url *common.URL) (router.Router, error) {
+func NewHealthCheckRouter(url *common.URL) (router.PriorityRouter, error) {
 	r := &HealthCheckRouter{
 		url:     url,
 		enabled: url.GetParamBool(HEALTH_ROUTE_ENABLED_KEY, false),
diff --git a/cluster/router/router.go b/cluster/router/router.go
index 9ee115443..1d1f79d27 100644
--- a/cluster/router/router.go
+++ b/cluster/router/router.go
@@ -23,34 +23,30 @@ import (
 )
 
 // Extension - Router
-
-// RouterFactory Router create factory
-type RouterFactory interface {
-	// NewRouter Create router instance with URL
-	NewRouter(*common.URL) (Router, error)
+// PriorityRouterFactory creates creates priority router with url
+type PriorityRouterFactory interface {
+	// NewPriorityRouter creates router instance with URL
+	NewPriorityRouter(*common.URL) (PriorityRouter, error)
 }
 
-// RouterFactory Router create factory use for parse config file
-type FileRouterFactory interface {
+// FilePriorityRouterFactory creates priority router with parse config file
+type FilePriorityRouterFactory interface {
 	// NewFileRouters Create file router with config file
-	NewFileRouter([]byte) (Router, error)
+	NewFileRouter([]byte) (PriorityRouter, error)
 }
 
 // Router
-type Router interface {
+type router interface {
 	// Route Determine the target invokers list.
 	Route([]protocol.Invoker, *common.URL, protocol.Invocation) []protocol.Invoker
-	// Priority Return Priority in router
-	// 0 to ^int(0) is better
-	Priority() int64
 	// URL Return URL in router
 	URL() common.URL
 }
 
-// Chain
-type Chain interface {
-	// Route Determine the target invokers list with chain.
-	Route([]protocol.Invoker, *common.URL, protocol.Invocation) []protocol.Invoker
-	// AddRouters Add routers
-	AddRouters([]Router)
+// Router
+type PriorityRouter interface {
+	router
+	// Priority Return Priority in router
+	// 0 to ^int(0) is better
+	Priority() int64
 }
diff --git a/cluster/router/tag/factory.go b/cluster/router/tag/factory.go
index d74924c89..a5d989cd3 100644
--- a/cluster/router/tag/factory.go
+++ b/cluster/router/tag/factory.go
@@ -31,17 +31,17 @@ func init() {
 type tagRouterFactory struct{}
 
 // NewTagRouterFactory create a tagRouterFactory
-func NewTagRouterFactory() router.RouterFactory {
+func NewTagRouterFactory() router.PriorityRouterFactory {
 	return &tagRouterFactory{}
 }
 
-// NewRouter create a tagRouter by tagRouterFactory with a url
+// NewPriorityRouter create a tagRouter by tagRouterFactory with a url
 // The url contains router configuration information
-func (c *tagRouterFactory) NewRouter(url *common.URL) (router.Router, error) {
+func (c *tagRouterFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) {
 	return NewTagRouter(url)
 }
 
 // NewFileRouter create a tagRouter by profile content
-func (c *tagRouterFactory) NewFileRouter(content []byte) (router.Router, error) {
+func (c *tagRouterFactory) NewFileRouter(content []byte) (router.PriorityRouter, error) {
 	return NewFileTagRouter(content)
 }
diff --git a/cluster/router/tag/factory_test.go b/cluster/router/tag/factory_test.go
index 58bff5b18..f11f29441 100644
--- a/cluster/router/tag/factory_test.go
+++ b/cluster/router/tag/factory_test.go
@@ -33,7 +33,7 @@ func TestTagRouterFactory_NewRouter(t *testing.T) {
 	u1, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true")
 	assert.Nil(t, err)
 	factory := NewTagRouterFactory()
-	tagRouter, e := factory.NewRouter(&u1)
+	tagRouter, e := factory.NewPriorityRouter(&u1)
 	assert.Nil(t, e)
 	assert.NotNil(t, tagRouter)
 }
diff --git a/common/extension/router_factory.go b/common/extension/router_factory.go
index 21a49d268..b61a05668 100644
--- a/common/extension/router_factory.go
+++ b/common/extension/router_factory.go
@@ -26,18 +26,18 @@ import (
 )
 
 var (
-	routers               = make(map[string]func() router.RouterFactory)
+	routers               = make(map[string]func() router.PriorityRouterFactory)
 	fileRouterFactoryOnce sync.Once
-	fileRouterFactories   = make(map[string]router.FileRouterFactory)
+	fileRouterFactories   = make(map[string]router.FilePriorityRouterFactory)
 )
 
 // SetRouterFactory sets create router factory function with @name
-func SetRouterFactory(name string, fun func() router.RouterFactory) {
+func SetRouterFactory(name string, fun func() router.PriorityRouterFactory) {
 	routers[name] = fun
 }
 
 // GetRouterFactory gets create router factory function by @name
-func GetRouterFactory(name string) router.RouterFactory {
+func GetRouterFactory(name string) router.PriorityRouterFactory {
 	if routers[name] == nil {
 		panic("router_factory for " + name + " is not existing, make sure you have import the package.")
 	}
@@ -45,12 +45,12 @@ func GetRouterFactory(name string) router.RouterFactory {
 }
 
 // GetRouterFactories gets all create router factory function
-func GetRouterFactories() map[string]func() router.RouterFactory {
+func GetRouterFactories() map[string]func() router.PriorityRouterFactory {
 	return routers
 }
 
 // GetFileRouterFactories gets all create file router factory instance
-func GetFileRouterFactories() map[string]router.FileRouterFactory {
+func GetFileRouterFactories() map[string]router.FilePriorityRouterFactory {
 	l := len(routers)
 	if l == 0 {
 		return nil
@@ -58,7 +58,7 @@ func GetFileRouterFactories() map[string]router.FileRouterFactory {
 	fileRouterFactoryOnce.Do(func() {
 		for k := range routers {
 			factory := GetRouterFactory(k)
-			if fr, ok := factory.(router.FileRouterFactory); ok {
+			if fr, ok := factory.(router.FilePriorityRouterFactory); ok {
 				fileRouterFactories[k] = fr
 			}
 		}
-- 
GitLab