diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go
index 952aedf92d70d92b3b029a9809826295e1cc7dc5..b4c7cea47b88491c05bb52f550b7dca86b7ae0dd 100644
--- a/cluster/router/chain/chain.go
+++ b/cluster/router/chain/chain.go
@@ -288,7 +288,9 @@ func isInvokersChanged(left []protocol.Invoker, right []protocol.Invoker) bool {
 	for _, r := range right {
 		found := false
 		for _, l := range left {
-			if common.IsEquals(l.GetUrl(), r.GetUrl(), constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY) {
+			lurl := l.GetUrl()
+			rurl := r.GetUrl()
+			if common.GetURLTool().CompareURLEqual(&lurl, &rurl, constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY) {
 				found = true
 				break
 			}
diff --git a/common/url_tool_extension.go b/common/url_tool_extension.go
new file mode 100644
index 0000000000000000000000000000000000000000..84899fca51deb47ca0194983db6afbd265c746ba
--- /dev/null
+++ b/common/url_tool_extension.go
@@ -0,0 +1,66 @@
+/*
+ * 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 common
+
+import "sync"
+
+var urlTool URLTool
+var lock sync.Mutex
+
+// Define some func for URL, such as comparison of URL.
+// Your can define your own implements, and invoke SetURLTool for high priority.
+type URLTool interface {
+	// The higher of the number, the higher of the priority.
+	Priority() uint8
+	// comparison of two URL, excluding some params
+	CompareURLEqual(*URL, *URL, ...string) bool
+}
+
+func SetURLTool(tool URLTool) {
+	lock.Lock()
+	defer lock.Unlock()
+	if urlTool == nil {
+		urlTool = tool
+		return
+	}
+	if urlTool.Priority() < tool.Priority() {
+		urlTool = tool
+	}
+}
+func GetURLTool() URLTool {
+	return urlTool
+}
+
+// Config default urlTools.
+func init() {
+	SetURLTool(defaultURLTool{})
+}
+
+type defaultURLTool struct {
+}
+
+// default priority is 16.
+func (defaultURLTool) Priority() uint8 {
+	//default is 16.
+	return 16
+}
+
+// default comparison implements
+func (defaultURLTool) CompareURLEqual(l *URL, r *URL, execludeParam ...string) bool {
+	return IsEquals(*l, *r, execludeParam...)
+}
diff --git a/common/url_tool_extension_test.go b/common/url_tool_extension_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8254c18aaa5c4eba110280db79f13b9e7c707075
--- /dev/null
+++ b/common/url_tool_extension_test.go
@@ -0,0 +1,84 @@
+/*
+ * 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 common
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestDefaultURLTool(t *testing.T) {
+	url1, _ := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=1556509797245")
+	url2, _ := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=155650979798")
+	assert.False(t, GetURLTool().CompareURLEqual(&url1, &url2))
+	assert.True(t, GetURLTool().CompareURLEqual(&url1, &url2, constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY))
+}
+
+func TestNewCustomURLTool(t *testing.T) {
+	url1, _ := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=1556509797245")
+	url2, _ := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=155650979798")
+	assert.True(t, GetURLTool().CompareURLEqual(&url1, &url2, constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY))
+	SetURLTool(customURLTool{})
+	assert.False(t, GetURLTool().CompareURLEqual(&url1, &url2))
+	assert.False(t, GetURLTool().CompareURLEqual(&url1, &url2, constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY))
+
+	url1, _ = NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000")
+	url2, _ = NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000")
+	assert.True(t, GetURLTool().CompareURLEqual(&url1, &url2))
+	assert.True(t, GetURLTool().CompareURLEqual(&url1, &url2, constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY))
+	SetURLTool(customURLTool{})
+	assert.True(t, GetURLTool().CompareURLEqual(&url1, &url2))
+	assert.True(t, GetURLTool().CompareURLEqual(&url1, &url2, constant.TIMESTAMP_KEY, constant.REMOTE_TIMESTAMP_KEY))
+}
+
+// just for no timestamp, it depend on write data.
+type customURLTool struct {
+}
+
+func (customURLTool) Priority() uint8 {
+	//default is 16.
+	return 32
+}
+func (customURLTool) CompareURLEqual(l *URL, r *URL, execludeParam ...string) bool {
+	return l.PrimitiveURL == r.PrimitiveURL
+}
diff --git a/registry/directory/directory.go b/registry/directory/directory.go
index 6f9c4fc889ddfd4b9949cc3115310e122678310e..2d75fe71d209f2f42319b6513a984e9ec5fd94fa 100644
--- a/registry/directory/directory.go
+++ b/registry/directory/directory.go
@@ -303,7 +303,8 @@ func (dir *RegistryDirectory) cacheInvoker(url *common.URL) protocol.Invoker {
 		} else {
 			// if cached invoker has the same URL with the new URL, then no need to re-refer, and no need to destroy
 			// the old invoker.
-			if common.IsEquals(*newUrl, cacheInvoker.(protocol.Invoker).GetUrl()) {
+			urlTmp := cacheInvoker.(protocol.Invoker).GetUrl()
+			if common.GetURLTool().CompareURLEqual(newUrl, &urlTmp) {
 				return nil
 			}