Merge pull request #2014 from ZLBer/resolve_placeholder

feat: resolve placeholder
diff --git a/.gitignore b/.gitignore
index 6605c27..01a7dbf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@
 classes
 
 # go mod, go test
+.go-version
 vendor/
 logs/
 .vscode/
diff --git a/cluster/cluster/available/cluster_invoker_test.go b/cluster/cluster/available/cluster_invoker_test.go
index 70919e6..cf20230 100644
--- a/cluster/cluster/available/cluster_invoker_test.go
+++ b/cluster/cluster/available/cluster_invoker_test.go
@@ -19,6 +19,7 @@
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"strings"
 	"testing"
@@ -51,7 +52,8 @@
 
 	invokers := []protocol.Invoker{}
 	invokers = append(invokers, invoker)
-	invoker.EXPECT().GetUrl().Return(availableUrl)
+	invoker.EXPECT().GetUrl().Return(availableUrl).AnyTimes()
+	invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
 
 	staticDir := static.NewDirectory(invokers)
 	clusterInvoker := availableCluster.Join(staticDir)
@@ -66,8 +68,8 @@
 	clusterInvoker := registerAvailable(invoker)
 
 	mockResult := &protocol.RPCResult{Rest: clusterpkg.Rest{Tried: 0, Success: true}}
-	invoker.EXPECT().IsAvailable().Return(true)
-	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 
 	result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
 
@@ -81,7 +83,10 @@
 	invoker := mock.NewMockInvoker(ctrl)
 	clusterInvoker := registerAvailable(invoker)
 
-	invoker.EXPECT().IsAvailable().Return(false)
+	invoker.EXPECT().IsAvailable().Return(false).AnyTimes()
+
+	res := &protocol.RPCResult{Err: errors.New("no provider available")}
+	invoker.EXPECT().Invoke(gomock.Any()).Return(res).AnyTimes()
 
 	result := clusterInvoker.Invoke(context.TODO(), &invocation.RPCInvocation{})
 
diff --git a/cluster/cluster/broadcast/cluster_invoker_test.go b/cluster/cluster/broadcast/cluster_invoker_test.go
index 74cd8cf..bd09e9e 100644
--- a/cluster/cluster/broadcast/cluster_invoker_test.go
+++ b/cluster/cluster/broadcast/cluster_invoker_test.go
@@ -49,11 +49,9 @@
 	extension.SetLoadbalance("random", random.NewRandomLoadBalance)
 
 	invokers := []protocol.Invoker{}
-	for i, ivk := range mockInvokers {
+	for _, ivk := range mockInvokers {
 		invokers = append(invokers, ivk)
-		if i == 0 {
-			ivk.EXPECT().GetUrl().Return(broadcastUrl)
-		}
+		ivk.EXPECT().GetUrl().Return(broadcastUrl).AnyTimes()
 	}
 	staticDir := static.NewDirectory(invokers)
 
@@ -72,7 +70,7 @@
 	for i := 0; i < 3; i++ {
 		invoker := mock.NewMockInvoker(ctrl)
 		invokers = append(invokers, invoker)
-		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	}
 
 	clusterInvoker := registerBroadcast(invokers...)
@@ -92,17 +90,17 @@
 	for i := 0; i < 10; i++ {
 		invoker := mock.NewMockInvoker(ctrl)
 		invokers = append(invokers, invoker)
-		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	}
 	{
 		invoker := mock.NewMockInvoker(ctrl)
 		invokers = append(invokers, invoker)
-		invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult).AnyTimes()
 	}
 	for i := 0; i < 10; i++ {
 		invoker := mock.NewMockInvoker(ctrl)
 		invokers = append(invokers, invoker)
-		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	}
 
 	clusterInvoker := registerBroadcast(invokers...)
diff --git a/cluster/cluster/failback/cluster_test.go b/cluster/cluster/failback/cluster_test.go
index 3b01e79..4bf022f 100644
--- a/cluster/cluster/failback/cluster_test.go
+++ b/cluster/cluster/failback/cluster_test.go
@@ -56,7 +56,7 @@
 	var invokers []protocol.Invoker
 	invokers = append(invokers, invoker)
 
-	invoker.EXPECT().GetUrl().Return(failbackUrl)
+	invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes()
 
 	staticDir := static.NewDirectory(invokers)
 	clusterInvoker := failbackCluster.Join(staticDir)
@@ -73,10 +73,10 @@
 
 	invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes()
 
-	invoker.EXPECT().IsAvailable().Return(true)
+	invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
 
 	mockResult := &protocol.RPCResult{Rest: clusterpkg.Rest{Tried: 0, Success: true}}
-	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 
 	result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
 	assert.Equal(t, mockResult, result)
@@ -121,7 +121,7 @@
 	wg.Wait()
 	assert.Equal(t, int64(0), clusterInvoker.taskList.Len())
 
-	invoker.EXPECT().Destroy().Return()
+	invoker.EXPECT().Destroy().Return().AnyTimes()
 	clusterInvoker.Destroy()
 
 	assert.Equal(t, int64(0), clusterInvoker.taskList.Len())
diff --git a/cluster/cluster/failfast/cluster_test.go b/cluster/cluster/failfast/cluster_test.go
index aa5dc6a..ed34e68 100644
--- a/cluster/cluster/failfast/cluster_test.go
+++ b/cluster/cluster/failfast/cluster_test.go
@@ -55,7 +55,7 @@
 	invokers = append(invokers, invoker)
 
 	invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
-	invoker.EXPECT().GetUrl().Return(failfastUrl)
+	invoker.EXPECT().GetUrl().Return(failfastUrl).AnyTimes()
 
 	staticDir := static.NewDirectory(invokers)
 	clusterInvoker := failfastCluster.Join(staticDir)
@@ -74,7 +74,7 @@
 
 	mockResult := &protocol.RPCResult{Rest: clusterpkg.Rest{Tried: 0, Success: true}}
 
-	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
 
 	assert.NoError(t, result.Error())
@@ -95,7 +95,7 @@
 
 	mockResult := &protocol.RPCResult{Err: perrors.New("error")}
 
-	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
 
 	assert.NotNil(t, result.Error())
diff --git a/cluster/cluster/failsafe/cluster_test.go b/cluster/cluster/failsafe/cluster_test.go
index 819d8fb..31796a4 100644
--- a/cluster/cluster/failsafe/cluster_test.go
+++ b/cluster/cluster/failsafe/cluster_test.go
@@ -55,7 +55,7 @@
 	invokers = append(invokers, invoker)
 	invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
 
-	invoker.EXPECT().GetUrl().Return(failsafeUrl)
+	invoker.EXPECT().GetUrl().Return(failsafeUrl).AnyTimes()
 
 	staticDir := static.NewDirectory(invokers)
 	clusterInvoker := failsafeCluster.Join(staticDir)
@@ -75,7 +75,7 @@
 
 	mockResult := &protocol.RPCResult{Rest: clusterpkg.Rest{Tried: 0, Success: true}}
 
-	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
 
 	assert.NoError(t, result.Error())
@@ -95,7 +95,7 @@
 
 	mockResult := &protocol.RPCResult{Err: perrors.New("error")}
 
-	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult).AnyTimes()
 	result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
 
 	assert.NoError(t, result.Error())
diff --git a/cluster/cluster/forking/cluster_test.go b/cluster/cluster/forking/cluster_test.go
index 0787300..427ba87 100644
--- a/cluster/cluster/forking/cluster_test.go
+++ b/cluster/cluster/forking/cluster_test.go
@@ -51,11 +51,9 @@
 	extension.SetLoadbalance(constant.LoadBalanceKeyRoundRobin, roundrobin.NewRRLoadBalance)
 
 	var invokers []protocol.Invoker
-	for i, ivk := range mockInvokers {
+	for _, ivk := range mockInvokers {
 		invokers = append(invokers, ivk)
-		if i == 0 {
-			ivk.EXPECT().GetUrl().Return(forkingUrl)
-		}
+		ivk.EXPECT().GetUrl().Return(forkingUrl).AnyTimes()
 	}
 	staticDir := static.NewDirectory(invokers)
 
@@ -145,14 +143,14 @@
 				func(protocol.Invocation) protocol.Result {
 					wg.Done()
 					return mockResult
-				})
+				}).AnyTimes()
 		} else {
 			invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
 				func(protocol.Invocation) protocol.Result {
 					time.Sleep(2 * time.Second)
 					wg.Done()
 					return mockResult
-				})
+				}).AnyTimes()
 		}
 	}
 
diff --git a/cluster/cluster/zoneaware/cluster_interceptor.go b/cluster/cluster/zoneaware/cluster_interceptor.go
index c92edc7..cb988cb 100644
--- a/cluster/cluster/zoneaware/cluster_interceptor.go
+++ b/cluster/cluster/zoneaware/cluster_interceptor.go
@@ -27,8 +27,7 @@
 	"dubbo.apache.org/dubbo-go/v3/protocol"
 )
 
-type interceptor struct {
-}
+type interceptor struct{}
 
 func (z *interceptor) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
 	key := constant.RegistryKey + "." + constant.RegistryZoneForceKey
diff --git a/cluster/cluster/zoneaware/cluster_invoker_test.go b/cluster/cluster/zoneaware/cluster_invoker_test.go
index a9ae7c9..db9ac41 100644
--- a/cluster/cluster/zoneaware/cluster_invoker_test.go
+++ b/cluster/cluster/zoneaware/cluster_invoker_test.go
@@ -63,7 +63,7 @@
 			invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
 				func(invocation protocol.Invocation) protocol.Result {
 					return mockResult
-				})
+				}).AnyTimes()
 		} else {
 			invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
 				func(invocation protocol.Invocation) protocol.Result {
diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go
index 037fa55..a9f9ce5 100644
--- a/cluster/router/chain/chain.go
+++ b/cluster/router/chain/chain.go
@@ -52,7 +52,19 @@
 
 // Route Loop routers in RouterChain and call Route method to determine the target invokers list.
 func (c *RouterChain) Route(url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
-	finalInvokers := c.invokers
+	finalInvokers := make([]protocol.Invoker, 0, len(c.invokers))
+	// multiple invoker may include different methods, find correct invoker otherwise
+	// will return the invoker without methods
+	for _, invoker := range c.invokers {
+		if invoker.GetURL().ServiceKey() == url.ServiceKey() {
+			finalInvokers = append(finalInvokers, invoker)
+		}
+	}
+
+	if len(finalInvokers) == 0 {
+		finalInvokers = c.invokers
+	}
+
 	for _, r := range c.copyRouters() {
 		finalInvokers = r.Route(finalInvokers, url, invocation)
 	}
diff --git a/cluster/router/tag/router.go b/cluster/router/tag/router.go
index d728772..d642a79 100644
--- a/cluster/router/tag/router.go
+++ b/cluster/router/tag/router.go
@@ -94,7 +94,6 @@
 		return
 	}
 	p.Process(&config_center.ConfigChangeEvent{Key: key, Value: value, ConfigType: remoting.EventTypeAdd})
-
 }
 
 func (p *PriorityRouter) Process(event *config_center.ConfigChangeEvent) {
diff --git a/cluster/router/tag/router_test.go b/cluster/router/tag/router_test.go
index 0ca3d39..22ddba7 100644
--- a/cluster/router/tag/router_test.go
+++ b/cluster/router/tag/router_test.go
@@ -354,7 +354,8 @@
  - name: tag1
    addresses: [192.168.0.1:20881]
  - name: tag2
-   addresses: [192.168.0.2:20882]`}
+   addresses: [192.168.0.2:20882]`,
+		}
 		dc, _ := mockFactory.GetDynamicConfiguration(ccUrl)
 		common_cfg.GetEnvInstance().SetDynamicConfiguration(dc)
 		p.Notify(invokerList)
@@ -380,7 +381,8 @@
 		extension.SetDefaultConfigurator(configurator.NewMockConfigurator)
 		ccUrl, _ := common.NewURL("mock://127.0.0.1:1111")
 		mockFactory := &config_center.MockDynamicConfigurationFactory{
-			Content: `xxxxxx`}
+			Content: `xxxxxx`,
+		}
 		dc, _ := mockFactory.GetDynamicConfiguration(ccUrl)
 		common_cfg.GetEnvInstance().SetDynamicConfiguration(dc)
 		p.Notify(invokerList)
diff --git a/common/url.go b/common/url.go
index c143cb2..75e2070 100644
--- a/common/url.go
+++ b/common/url.go
@@ -284,6 +284,11 @@
 	return c.GetParam(constant.GroupKey, "")
 }
 
+// Interface get interface
+func (c *URL) Interface() string {
+	return c.GetParam(constant.InterfaceKey, "")
+}
+
 // Version get group
 func (c *URL) Version() string {
 	return c.GetParam(constant.VersionKey, "")
@@ -356,7 +361,7 @@
 	return buildString
 }
 
-//GetCacheInvokerMapKey get directory cacheInvokerMap key
+// GetCacheInvokerMapKey get directory cacheInvokerMap key
 func (c *URL) GetCacheInvokerMapKey() string {
 	urlNew, _ := NewURL(c.PrimitiveURL)
 
@@ -369,7 +374,7 @@
 
 // ServiceKey gets a unique key of a service.
 func (c *URL) ServiceKey() string {
-	return ServiceKey(c.GetParam(constant.InterfaceKey, strings.TrimPrefix(c.Path, "/")),
+	return ServiceKey(c.GetParam(constant.InterfaceKey, strings.TrimPrefix(c.Path, constant.PathSeparator)),
 		c.GetParam(constant.GroupKey, ""), c.GetParam(constant.VersionKey, ""))
 }
 
@@ -861,7 +866,7 @@
 	return compareURLEqualFunc
 }
 
-//GetParamDuration get duration if param is invalid or missing will return 3s
+// GetParamDuration get duration if param is invalid or missing will return 3s
 func (c *URL) GetParamDuration(s string, d string) time.Duration {
 	if t, err := time.ParseDuration(c.GetParam(s, d)); err == nil {
 		return t
diff --git a/config/graceful_shutdown.go b/config/graceful_shutdown.go
index 6b81c5d..54ed81b 100644
--- a/config/graceful_shutdown.go
+++ b/config/graceful_shutdown.go
@@ -71,7 +71,7 @@
 		filter.Set(constant.GracefulShutdownFilterShutdownConfig, GetShutDown())
 	}
 
-	if GetShutDown().InternalSignal {
+	if GetShutDown().GetInternalSignal() {
 		signals := make(chan os.Signal, 1)
 		signal.Notify(signals, ShutdownSignals...)
 
diff --git a/config/graceful_shutdown_config.go b/config/graceful_shutdown_config.go
index d0779a8..044087b 100644
--- a/config/graceful_shutdown_config.go
+++ b/config/graceful_shutdown_config.go
@@ -66,7 +66,7 @@
 	// when we try to shutdown the applicationConfig, we will reject the new requests. In most cases, you don't need to configure this.
 	RejectRequestHandler string `yaml:"reject-handler" json:"reject-handler,omitempty" property:"reject_handler"`
 	// internal listen kill signal,the default is true.
-	InternalSignal bool `default:"true" yaml:"internal-signal" json:"internal.signal,omitempty" property:"internal.signal"`
+	InternalSignal *bool `default:"true" yaml:"internal-signal" json:"internal.signal,omitempty" property:"internal.signal"`
 	// offline request window length
 	OfflineRequestWindowTimeout string `yaml:"offline-request-window-timeout" json:"offlineRequestWindowTimeout,omitempty" property:"offlineRequestWindowTimeout"`
 	// true -> new request will be rejected.
@@ -124,6 +124,13 @@
 	return result
 }
 
+func (config *ShutdownConfig) GetInternalSignal() bool {
+	if config.InternalSignal == nil {
+		return false
+	}
+	return *config.InternalSignal
+}
+
 func (config *ShutdownConfig) Init() error {
 	return defaults.Set(config)
 }
@@ -157,12 +164,12 @@
 }
 
 func (scb *ShutdownConfigBuilder) SetInternalSignal(internalSignal bool) *ShutdownConfigBuilder {
-	scb.shutdownConfig.InternalSignal = internalSignal
+	scb.shutdownConfig.InternalSignal = &internalSignal
 	return scb
 }
 
 func (scb *ShutdownConfigBuilder) Build() *ShutdownConfig {
-	defaults.Set(scb)
+	defaults.MustSet(scb.shutdownConfig)
 	return scb.shutdownConfig
 }
 
diff --git a/config/graceful_shutdown_config_test.go b/config/graceful_shutdown_config_test.go
index c76098b..fe6890d 100644
--- a/config/graceful_shutdown_config_test.go
+++ b/config/graceful_shutdown_config_test.go
@@ -68,7 +68,7 @@
 		SetOfflineRequestWindowTimeout("13s").
 		SetRejectRequestHandler("handler").
 		SetRejectRequest(true).
-		SetInternalSignal(true).
+		SetInternalSignal(false).
 		Build()
 
 	assert.Equal(t, config.Prefix(), constant.ShutdownConfigPrefix)
@@ -86,4 +86,18 @@
 
 	waitTime := config.GetConsumerUpdateWaitTime()
 	assert.Equal(t, waitTime, 3*time.Second)
+
+	assert.Equal(t, config.GetInternalSignal(), false)
+}
+
+func TestGetInternalSignal(t *testing.T) {
+	config := NewShutDownConfigBuilder().
+		SetTimeout("10s").
+		SetStepTimeout("15s").
+		SetOfflineRequestWindowTimeout("13s").
+		SetRejectRequestHandler("handler").
+		SetRejectRequest(true).
+		Build()
+
+	assert.Equal(t, config.GetInternalSignal(), true)
 }
diff --git a/go.mod b/go.mod
index ea0f397..920b29b 100644
--- a/go.mod
+++ b/go.mod
@@ -35,7 +35,7 @@
 	github.com/magiconair/properties v1.8.6
 	github.com/mitchellh/mapstructure v1.5.0
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
-	github.com/nacos-group/nacos-sdk-go v1.1.1
+	github.com/nacos-group/nacos-sdk-go v1.1.2
 	github.com/natefinch/lumberjack v2.0.0+incompatible
 	github.com/opentracing/opentracing-go v1.2.0
 	github.com/pkg/errors v0.9.1
@@ -45,12 +45,12 @@
 	github.com/stretchr/testify v1.8.0
 	go.etcd.io/etcd/api/v3 v3.5.4
 	go.etcd.io/etcd/client/v3 v3.5.4
-	go.opentelemetry.io/otel v1.8.0
-	go.opentelemetry.io/otel/trace v1.8.0
+	go.opentelemetry.io/otel v1.9.0
+	go.opentelemetry.io/otel/trace v1.9.0
 	go.uber.org/atomic v1.9.0
 	go.uber.org/zap v1.21.0
 	google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247
 	google.golang.org/grpc v1.48.0
-	google.golang.org/protobuf v1.28.0
+	google.golang.org/protobuf v1.28.1
 	gopkg.in/yaml.v2 v2.4.0
 )
diff --git a/go.sum b/go.sum
index c0b5bc1..8442bad 100644
--- a/go.sum
+++ b/go.sum
@@ -560,8 +560,8 @@
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA=
-github.com/nacos-group/nacos-sdk-go v1.1.1 h1:beczWcOoTaVBMgCgikqvZflrN5Xbw7pWAWpxl+VJGIA=
-github.com/nacos-group/nacos-sdk-go v1.1.1/go.mod h1:UHOtQNQY/qpk2dhg6gDq8u5+/CEIc3+lWmrmxEzX0/g=
+github.com/nacos-group/nacos-sdk-go v1.1.2 h1:lWTpf5SXLetQetS7p31eGic/ncqsnn0Zbau1i3eC25Y=
+github.com/nacos-group/nacos-sdk-go v1.1.2/go.mod h1:I8Vj4M8ZLpBk7EY2A8RXQE1SbfCA7b56TJBPIFTrUYE=
 github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
 github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
 github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
@@ -689,8 +689,9 @@
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
-github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
@@ -796,10 +797,10 @@
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
 go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
-go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg=
-go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
-go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY=
-go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
+go.opentelemetry.io/otel v1.9.0 h1:8WZNQFIB2a71LnANS9JeyidJKKGOOremcUtb/OtHISw=
+go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo=
+go.opentelemetry.io/otel/trace v1.9.0 h1:oZaCNJUjWcg60VXWee8lJKlqhPbXAPB51URuR47pQYc=
+go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@@ -1209,8 +1210,8 @@
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/metadata/definition/definition.go b/metadata/definition/definition.go
index f1241d1..2cb11e3 100644
--- a/metadata/definition/definition.go
+++ b/metadata/definition/definition.go
@@ -21,6 +21,7 @@
 	"bytes"
 	"encoding/json"
 	"fmt"
+	"sort"
 	"strings"
 )
 
@@ -70,8 +71,8 @@
 
 // FullServiceDefinition is the describer of service definition with parameters
 type FullServiceDefinition struct {
+	Parameters map[string]string
 	ServiceDefinition
-	Params map[string]string
 }
 
 // MethodDefinition is the describer of method definition
@@ -121,6 +122,56 @@
 	return sd
 }
 
+// BuildFullDefinition can build service definition with full url parameters
+func BuildFullDefinition(service common.Service, url *common.URL) *FullServiceDefinition {
+	fsd := &FullServiceDefinition{}
+	sd := BuildServiceDefinition(service, url)
+	fsd.ServiceDefinition = *sd
+	fsd.Parameters = make(map[string]string)
+	for k, v := range url.GetParams() {
+		fsd.Parameters[k] = strings.Join(v, ",")
+	}
+	return fsd
+}
+
+// ToBytes convert ServiceDefinition to json string
+func (def *FullServiceDefinition) ToBytes() ([]byte, error) {
+	return json.Marshal(def)
+}
+
+// String will iterate all methods and parameters and convert them to json string
+func (def *FullServiceDefinition) String() string {
+	var methodStr strings.Builder
+	for _, m := range def.Methods {
+		var paramType strings.Builder
+		for _, p := range m.ParameterTypes {
+			paramType.WriteString(fmt.Sprintf("{type:%v}", p))
+		}
+		var param strings.Builder
+		for _, d := range m.Parameters {
+			param.WriteString(fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.ID, d.Type, d.TypeBuilderName))
+		}
+		methodStr.WriteString(fmt.Sprintf("{name:%v,parameterTypes:[%v],returnType:%v,params:[%v] }", m.Name, paramType.String(), m.ReturnType, param.String()))
+	}
+	var types strings.Builder
+	for _, d := range def.Types {
+		types.WriteString(fmt.Sprintf("{id:%v,type:%v,builderName:%v}", d.ID, d.Type, d.TypeBuilderName))
+	}
+
+	sortSlice := make([]string, 0)
+	var parameters strings.Builder
+	for k := range def.Parameters {
+		sortSlice = append(sortSlice, k)
+	}
+	sort.Slice(sortSlice, func(i, j int) bool { return sortSlice[i] < sortSlice[j] })
+	for _, k := range sortSlice {
+		parameters.WriteString(fmt.Sprintf("%v:%v,", k, def.Parameters[k]))
+	}
+
+	return fmt.Sprintf("{parameters:{%v}, canonicalName:%v, codeSource:%v, methods:[%v], types:[%v]}",
+		strings.TrimRight(parameters.String(), ","), def.CanonicalName, def.CodeSource, methodStr.String(), types.String())
+}
+
 // ServiceDescriperBuild builds the service key, format is `group/serviceName:version` which be same as URL's service key
 func ServiceDescriperBuild(serviceName string, group string, version string) string {
 	buf := &bytes.Buffer{}
diff --git a/metadata/definition/definition_test.go b/metadata/definition/definition_test.go
index 6989fb7..7515b09 100644
--- a/metadata/definition/definition_test.go
+++ b/metadata/definition/definition_test.go
@@ -48,4 +48,6 @@
 	service := common.ServiceMap.GetServiceByServiceKey(url.Protocol, url.ServiceKey())
 	sd := BuildServiceDefinition(*service, url)
 	assert.Equal(t, "{canonicalName:com.ikurento.user.UserProvider, codeSource:, methods:[{name:GetUser,parameterTypes:[{type:slice}],returnType:ptr,params:[] }], types:[]}", sd.String())
+	fsd := BuildFullDefinition(*service, url)
+	assert.Equal(t, "{parameters:{anyhost:true,application:BDTService,bean.name:UserProvider,category:providers,default.timeout:10000,dubbo:dubbo-provider-golang-1.0.0,environment:dev,group:group1,interface:com.ikurento.user.UserProvider,ip:192.168.56.1,methods:GetUser,module:dubbogo user-info server,org:ikurento.com,owner:ZX,pid:1447,revision:0.0.1,side:provider,timeout:3000,timestamp:1556509797245,version:0.0.1}, canonicalName:com.ikurento.user.UserProvider, codeSource:, methods:[{name:GetUser,parameterTypes:[{type:slice}],returnType:ptr,params:[] }], types:[]}", fsd.String())
 }
diff --git a/metadata/service/local/service.go b/metadata/service/local/service.go
index 2b2e6ac..aeac070 100644
--- a/metadata/service/local/service.go
+++ b/metadata/service/local/service.go
@@ -202,7 +202,7 @@
 	isGeneric := url.GetParamBool(constant.GenericKey, false)
 	if len(interfaceName) > 0 && !isGeneric {
 		tmpService := common.ServiceMap.GetServiceByServiceKey(url.Protocol, url.ServiceKey())
-		sd := definition.BuildServiceDefinition(*tmpService, url)
+		sd := definition.BuildFullDefinition(*tmpService, url)
 		data, err := sd.ToBytes()
 		if err != nil {
 			logger.Errorf("publishProvider getServiceDescriptor error. providerUrl:%v , error:%v ", url, err)
diff --git a/metadata/service/local/service_test.go b/metadata/service/local/service_test.go
index c3bcc50..031c8a5 100644
--- a/metadata/service/local/service_test.go
+++ b/metadata/service/local/service_test.go
@@ -99,7 +99,14 @@
 	assert.NoError(t, err)
 	err = mts.PublishServiceDefinition(u)
 	assert.NoError(t, err)
-	expected := "{\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," +
+	expected := "{\"Parameters\":{\"anyhost\":\"true\",\"application\":\"BDTService\"," +
+		"\"bean.name\":\"UserProvider\",\"category\":\"providers\",\"default.timeout\":\"10000\"," +
+		"\"dubbo\":\"dubbo-provider-golang-1.0.0\",\"environment\":\"dev\",\"group\":\"group1\"," +
+		"\"interface\":\"com.ikurento.user.UserProvider\",\"ip\":\"192.168.56.1\"," +
+		"\"methods\":\"GetUser\",\"module\":\"dubbogo user-info server\",\"org\":\"ikurento.com\"," +
+		"\"owner\":\"ZX\",\"pid\":\"1447\",\"revision\":\"0.0.1\",\"side\":\"provider\"," +
+		"\"timeout\":\"3000\",\"timestamp\":\"1556509797245\",\"version\":\"0.0.1\"}," +
+		"\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," +
 		"\"Methods\":[{\"Name\":\"GetUser\",\"ParameterTypes\":[\"slice\"],\"ReturnType\":\"ptr\"," +
 		"\"Parameters\":null}],\"Types\":null}"
 	def1, err := mts.GetServiceDefinition(serviceName, group, version)
diff --git a/metadata/service/remote/service.go b/metadata/service/remote/service.go
index aaf6aae..9b2ba39 100644
--- a/metadata/service/remote/service.go
+++ b/metadata/service/remote/service.go
@@ -109,7 +109,7 @@
 	if common.RoleType(common.PROVIDER).Role() == url.GetParam(constant.SideKey, "") {
 		if len(interfaceName) > 0 && !isGeneric {
 			sv := common.ServiceMap.GetServiceByServiceKey(url.Protocol, url.ServiceKey())
-			sd := definition.BuildServiceDefinition(*sv, url)
+			sd := definition.BuildFullDefinition(*sv, url)
 			id := &identifier.MetadataIdentifier{
 				BaseMetadataIdentifier: identifier.BaseMetadataIdentifier{
 					ServiceInterface: interfaceName,
diff --git a/metadata/service/remote/service_test.go b/metadata/service/remote/service_test.go
index ae1eeea..fa4a17e 100644
--- a/metadata/service/remote/service_test.go
+++ b/metadata/service/remote/service_test.go
@@ -146,9 +146,17 @@
 	err = mts.PublishServiceDefinition(u)
 	assert.NoError(t, err)
 
-	expected := "{\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," +
+	expected := "{\"Parameters\":{\"anyhost\":\"true\",\"application\":\"BDTService\"," +
+		"\"bean.name\":\"UserProvider\",\"category\":\"providers\",\"default.timeout\":\"10000\"," +
+		"\"dubbo\":\"dubbo-provider-golang-1.0.0\",\"environment\":\"dev\",\"group\":\"group1\"," +
+		"\"interface\":\"com.ikurento.user.UserProvider\",\"ip\":\"192.168.56.1\"," +
+		"\"methods\":\"GetUser\",\"module\":\"dubbogo user-info server\",\"org\":\"ikurento.com\"," +
+		"\"owner\":\"ZX\",\"pid\":\"1447\",\"revision\":\"0.0.1\",\"side\":\"provider\"," +
+		"\"timeout\":\"3000\",\"timestamp\":\"1556509797245\",\"version\":\"0.0.1\"}," +
+		"\"CanonicalName\":\"com.ikurento.user.UserProvider\",\"CodeSource\":\"\"," +
 		"\"Methods\":[{\"Name\":\"GetUser\",\"ParameterTypes\":[\"slice\"],\"ReturnType\":\"ptr\"," +
 		"\"Parameters\":null}],\"Types\":null}"
+
 	def1, _ := mts.GetServiceDefinition(serviceName, group, version)
 	assert.Equal(t, expected, def1)
 	serviceKey := definition.ServiceDescriperBuild(serviceName, group, version)
diff --git a/registry/polaris/core.go b/registry/polaris/core.go
index 8c82b7b..e87fac7 100644
--- a/registry/polaris/core.go
+++ b/registry/polaris/core.go
@@ -57,9 +57,8 @@
 // AddSubscriber add subscriber into watcher's subscribers
 func (watcher *PolarisServiceWatcher) AddSubscriber(subscriber func(remoting.EventType, []model.Instance)) {
 
-	watcher.lazyRun()
-
 	watcher.lock.Lock()
+	watcher.lazyRun()
 	defer watcher.lock.Unlock()
 
 	watcher.subscribers = append(watcher.subscribers, subscriber)
@@ -74,48 +73,50 @@
 
 // startWatch start run work to watch target service by polaris
 func (watcher *PolarisServiceWatcher) startWatch() {
-
 	for {
 		resp, err := watcher.consumer.WatchService(watcher.subscribeParam)
 		if err != nil {
 			time.Sleep(time.Duration(500 * time.Millisecond))
 			continue
 		}
-
 		watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
 			Value:      resp.GetAllInstancesResp.Instances,
 			ConfigType: remoting.EventTypeAdd,
 		})
 
-		select {
-		case event := <-resp.EventChannel:
-			eType := event.GetSubScribeEventType()
-			if eType == api.EventInstance {
-				insEvent := event.(*model.InstanceEvent)
-				if insEvent.AddEvent != nil {
-					watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
-						Value:      insEvent.AddEvent.Instances,
-						ConfigType: remoting.EventTypeAdd,
-					})
-				}
-				if insEvent.UpdateEvent != nil {
-					instances := make([]model.Instance, len(insEvent.UpdateEvent.UpdateList))
-					for i := range insEvent.UpdateEvent.UpdateList {
-						instances[i] = insEvent.UpdateEvent.UpdateList[i].After
+		for {
+			select {
+			case event := <-resp.EventChannel:
+				eType := event.GetSubScribeEventType()
+				if eType == api.EventInstance {
+					insEvent := event.(*model.InstanceEvent)
+
+					if insEvent.AddEvent != nil {
+						watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+							Value:      insEvent.AddEvent.Instances,
+							ConfigType: remoting.EventTypeAdd,
+						})
 					}
-					watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
-						Value:      instances,
-						ConfigType: remoting.EventTypeUpdate,
-					})
-				}
-				if insEvent.DeleteEvent != nil {
-					watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
-						Value:      insEvent.DeleteEvent.Instances,
-						ConfigType: remoting.EventTypeDel,
-					})
+					if insEvent.UpdateEvent != nil {
+						instances := make([]model.Instance, len(insEvent.UpdateEvent.UpdateList))
+						for i := range insEvent.UpdateEvent.UpdateList {
+							instances[i] = insEvent.UpdateEvent.UpdateList[i].After
+						}
+						watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+							Value:      instances,
+							ConfigType: remoting.EventTypeUpdate,
+						})
+					}
+					if insEvent.DeleteEvent != nil {
+						watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+							Value:      insEvent.DeleteEvent.Instances,
+							ConfigType: remoting.EventTypeDel,
+						})
+					}
 				}
 			}
 		}
+
 	}
 }
 
diff --git a/registry/zookeeper/service_discovery_test.go b/registry/zookeeper/service_discovery_test.go
index 477fa5e..20e2e46 100644
--- a/registry/zookeeper/service_discovery_test.go
+++ b/registry/zookeeper/service_discovery_test.go
@@ -17,265 +17,132 @@
 
 package zookeeper
 
-//
-//import (
-//	"context"
-//	"strconv"
-//	"sync"
-//	"testing"
-//)
-//
-//import (
-//	"github.com/dubbogo/go-zookeeper/zk"
-//
-//	gxset "github.com/dubbogo/gost/container/set"
-//
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"dubbo.apache.org/dubbo-go/v3/common"
-//	"dubbo.apache.org/dubbo-go/v3/common/constant"
-//	"dubbo.apache.org/dubbo-go/v3/common/extension"
-//	"github.com/dubbogo/gost/gof/observer"
-//	"dubbo.apache.org/dubbo-go/v3/common/observer/dispatcher"
-//	"dubbo.apache.org/dubbo-go/v3/config"
-//	"dubbo.apache.org/dubbo-go/v3/metadata/mapping"
-//	"dubbo.apache.org/dubbo-go/v3/protocol"
-//	"dubbo.apache.org/dubbo-go/v3/registry"
-//	"dubbo.apache.org/dubbo-go/v3/registry/event"
-//)
-//
-//const testName = "test"
-//
-//func prepareData(t *testing.T) *zk.TestCluster {
-//	var err error
-//	tc, err := zk.StartTestCluster(1, nil, nil)
-//	assert.NoError(t, err)
-//	assert.NotNil(t, tc.Servers[0])
-//	address := "127.0.0.1:" + strconv.Itoa(tc.Servers[0].Port)
-//	//address := "127.0.0.1:2181"
-//
-//	config.GetRootConfig().ServiceDiscoveries[testName] = &config.ServiceDiscoveryConfig{
-//		Protocol:  "zookeeper",
-//		RemoteRef: "test",
-//	}
-//
-//	config.GetRootConfig().Remotes[testName] = &config.RemoteConfig{
-//		Address:    address,
-//		TimeoutStr: "10s",
-//	}
-//	return tc
-//}
-//
-//func TestNewZookeeperServiceDiscovery(t *testing.T) {
-//	_, err := newZookeeperServiceDiscovery()
-//
-//	// the ShutdownConfig not found
-//	// err: could not init the instance because the config is invalid
-//	assert.NotNil(t, err)
-//
-//	//sdc := &config.ServiceDiscoveryConfig{
-//	//	Protocol:  "zookeeper",
-//	//	RemoteRef: "mock",
-//	//}
-//	//config.GetRootConfig().ServiceDiscoveries[name] = sdc
-//	_, err = newZookeeperServiceDiscovery()
-//
-//	// RemoteConfig not found
-//	// err: could not find the remote config for name: mock
-//	assert.NotNil(t, err)
-//}
-//
-//func TestZookeeperServiceDiscovery_CURDAndListener(t *testing.T) {
-//	tc := prepareData(t)
-//	defer func() {
-//		_ = tc.Stop()
-//	}()
-//	t.Run("testCURDZookeeperServiceDiscovery", testCURDZookeeperServiceDiscovery)
-//	t.Run("testAddListenerZookeeperServiceDiscovery", testAddListenerZookeeperServiceDiscovery)
-//}
-//
-//func testCURDZookeeperServiceDiscovery(t *testing.T) {
-//	prepareData(t)
-//	extension.SetEventDispatcher("mock", func() observer.EventDispatcher {
-//		return dispatcher.NewMockEventDispatcher()
-//	})
-//	extension.SetGlobalServiceNameMapping(func() mapping.ServiceNameMapping {
-//		return mapping.NewMockServiceNameMapping()
-//	})
-//
-//	extension.SetProtocol("mock", func() protocol.Protocol {
-//		return &mockProtocol{}
-//	})
-//
-//	sd, err := newZookeeperServiceDiscovery()
-//	assert.Nil(t, err)
-//	defer func() {
-//		_ = sd.Destroy()
-//	}()
-//	ins := &registry.DefaultServiceInstance{
-//		ID:          "testID",
-//		ServiceName: testName,
-//		Host:        "127.0.0.1",
-//		Port:        2233,
-//		Enable:      true,
-//		Healthy:     true,
-//		Metadata:    nil,
-//	}
-//	ins.Metadata = map[string]string{"t1": "test1", constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME: `{"protocol":"mock","timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"2233"}`}
-//	err = sd.Register(ins)
-//
-//	assert.Nil(t, err)
-//
-//	testsPager := sd.GetHealthyInstancesByPage(testName, 0, 1, true)
-//	assert.Equal(t, 1, testsPager.GetDataSize())
-//	assert.Equal(t, 1, testsPager.GetTotalPages())
-//	test := testsPager.GetData()[0].(registry.ServiceInstance)
-//	assert.Equal(t, "127.0.0.1:2233", test.GetID())
-//	assert.Equal(t, "test1", test.GetMetadata()["t1"])
-//
-//	ins = &registry.DefaultServiceInstance{
-//		ID:          "testID",
-//		ServiceName: testName,
-//		Host:        "127.0.0.1",
-//		Port:        2233,
-//		Enable:      true,
-//		Healthy:     true,
-//	}
-//	ins.Metadata = map[string]string{"t1": "test12", constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME: `{"protocol":"mock","timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"2233"}`}
-//
-//	err = sd.Update(ins)
-//
-//	assert.Nil(t, err)
-//
-//	testsPager = sd.GetInstancesByPage(testName, 0, 1)
-//	assert.Equal(t, 1, testsPager.GetDataSize())
-//	test = testsPager.GetData()[0].(registry.ServiceInstance)
-//	assert.Equal(t, "test12", test.GetMetadata()["t1"])
-//
-//	testsMap := sd.GetRequestInstances([]string{testName}, 0, 1)
-//	assert.Equal(t, 1, len(testsMap))
-//	assert.Equal(t, 1, testsMap[testName].GetDataSize())
-//	test = testsMap[testName].GetData()[0].(registry.ServiceInstance)
-//	assert.Equal(t, "test12", test.GetMetadata()["t1"])
-//
-//	names := sd.GetServices()
-//	assert.Equal(t, 1, names.Size())
-//	assert.Equal(t, testName, names.Values()[0])
-//
-//	err = sd.Unregister(&registry.DefaultServiceInstance{
-//		ID:          "testID",
-//		ServiceName: testName,
-//		Host:        "127.0.0.1",
-//		Port:        2233,
-//		Enable:      true,
-//		Healthy:     true,
-//		Metadata:    nil,
-//	})
-//	assert.Nil(t, err)
-//}
-//
-//func testAddListenerZookeeperServiceDiscovery(t *testing.T) {
-//	sd, err := newZookeeperServiceDiscovery()
-//	assert.Nil(t, err)
-//	defer func() {
-//		_ = sd.Destroy()
-//	}()
-//
-//	ins := &registry.DefaultServiceInstance{
-//		ID:          "testID",
-//		ServiceName: testName,
-//		Host:        "127.0.0.1",
-//		Port:        2233,
-//		Enable:      true,
-//		Healthy:     true,
-//		Metadata:    nil,
-//	}
-//	ins.Metadata = map[string]string{"t1": "test12", constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME: `{"protocol":"mock","timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"2233"}`}
-//	err = sd.Register(ins)
-//
-//	assert.Nil(t, err)
-//	wg := &sync.WaitGroup{}
-//	wg.Add(1)
-//	tn := &testNotify{
-//		wg: wg,
-//		t:  t,
-//	}
-//	hs := gxset.NewSet()
-//	hs.Add(testName)
-//
-//	sicl := event.NewServiceInstancesChangedListener(hs)
-//	sicl.AddListenerAndNotify(testName, tn)
-//	extension.SetAndInitGlobalDispatcher("direct")
-//	extension.GetGlobalDispatcher().AddEventListener(sicl)
-//	err = sd.AddListener(sicl)
-//	assert.NoError(t, err)
-//
-//	ins = &registry.DefaultServiceInstance{
-//		ID:          "testID",
-//		ServiceName: testName,
-//		Host:        "127.0.0.1",
-//		Port:        2233,
-//		Enable:      true,
-//		Healthy:     true,
-//		Metadata:    nil,
-//	}
-//	ins.Metadata = map[string]string{"t1": "test12", constant.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME: `{"protocol":"mock","timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"2233"}`}
-//	err = sd.Update(ins)
-//	assert.NoError(t, err)
-//	tn.wg.Wait()
-//}
-//
-//type testNotify struct {
-//	wg *sync.WaitGroup
-//	t  *testing.T
-//}
-//
-//func (tn *testNotify) Notify(e *registry.ServiceEvent) {
-//	assert.Equal(tn.t, "2233", e.Service.Port)
-//	tn.wg.Done()
-//}
-//func (tn *testNotify) NotifyAll([]*registry.ServiceEvent, func()) {
-//
-//}
-//
-//type mockProtocol struct{}
-//
-//func (m mockProtocol) Export(protocol.Invoker) protocol.Exporter {
-//	panic("implement me")
-//}
-//
-//func (m mockProtocol) Refer(*common.URL) protocol.Invoker {
-//	return &mockInvoker{}
-//}
-//
-//func (m mockProtocol) Destroy() {
-//	panic("implement me")
-//}
-//
-//type mockInvoker struct{}
-//
-//func (m *mockInvoker) GetURL() *common.URL {
-//	panic("implement me")
-//}
-//
-//func (m *mockInvoker) IsAvailable() bool {
-//	panic("implement me")
-//}
-//
-//func (m *mockInvoker) Destroy() {
-//	panic("implement me")
-//}
-//
-//func (m *mockInvoker) Invoke(context.Context, protocol.Invocation) protocol.Result {
-//	// for getMetadataInfo and ServiceInstancesChangedListenerImpl onEvent
-//	serviceInfo := &common.ServiceInfo{ServiceKey: "test", MatchKey: "test"}
-//	services := make(map[string]*common.ServiceInfo)
-//	services["test"] = serviceInfo
-//	return &protocol.RPCResult{
-//		Rest: &common.MetadataInfo{
-//			Services: services,
-//		},
-//	}
-//}
+import (
+	"context"
+	"sync"
+	"testing"
+)
+
+import (
+	"github.com/nacos-group/nacos-sdk-go/model"
+	"github.com/nacos-group/nacos-sdk-go/vo"
+
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"dubbo.apache.org/dubbo-go/v3/common"
+	"dubbo.apache.org/dubbo-go/v3/common/constant"
+	"dubbo.apache.org/dubbo-go/v3/protocol"
+	"dubbo.apache.org/dubbo-go/v3/registry"
+)
+
+func Test_newZookeeperServiceDiscovery(t *testing.T) {
+	url, _ := common.NewURL("dubbo://127.0.0.1:2181",
+		common.WithParamsValue(constant.ClientNameKey, "zk-client"))
+	sd, err := newZookeeperServiceDiscovery(url)
+	assert.Nil(t, err)
+	err = sd.Destroy()
+	assert.Nil(t, err)
+
+}
+func Test_zookeeperServiceDiscovery_DataChange(t *testing.T) {
+	serviceDiscovery := &zookeeperServiceDiscovery{}
+	assert.Equal(t, registry.DefaultPageSize, serviceDiscovery.GetDefaultPageSize())
+}
+
+type testNotify struct {
+	wg *sync.WaitGroup
+	t  *testing.T
+}
+
+func (tn *testNotify) Notify(e *registry.ServiceEvent) {
+	assert.Equal(tn.t, "2181", e.Service.Port)
+	tn.wg.Done()
+}
+
+func (tn *testNotify) NotifyAll([]*registry.ServiceEvent, func()) {}
+
+type mockClient struct {
+	instance []interface{}
+}
+
+func (c mockClient) RegisterInstance(param vo.RegisterInstanceParam) (bool, error) {
+	return true, nil
+}
+
+func (c mockClient) DeregisterInstance(param vo.DeregisterInstanceParam) (bool, error) {
+	return true, nil
+}
+
+func (c mockClient) UpdateInstance(param vo.UpdateInstanceParam) (bool, error) {
+	return true, nil
+}
+
+func (c mockClient) GetService(param vo.GetServiceParam) (model.Service, error) {
+	panic("implement me")
+}
+
+func (c mockClient) SelectInstances(param vo.SelectInstancesParam) ([]model.Instance, error) {
+	panic("implement me")
+}
+
+func (c mockClient) SelectAllInstances(param vo.SelectAllInstancesParam) ([]model.Instance, error) {
+	panic("implement me")
+}
+
+func (c mockClient) SelectOneHealthyInstance(param vo.SelectOneHealthInstanceParam) (*model.Instance, error) {
+	panic("implement me")
+}
+
+func (c mockClient) Subscribe(param *vo.SubscribeParam) error {
+	return nil
+}
+
+func (c mockClient) Unsubscribe(param *vo.SubscribeParam) error {
+	panic("implement me")
+}
+
+func (c mockClient) GetAllServicesInfo(param vo.GetAllServiceInfoParam) (model.ServiceList, error) {
+	panic("implement me")
+}
+
+type mockProtocol struct{}
+
+func (m mockProtocol) Export(protocol.Invoker) protocol.Exporter {
+	panic("implement me")
+}
+
+func (m mockProtocol) Refer(*common.URL) protocol.Invoker {
+	return &mockInvoker{}
+}
+
+func (m mockProtocol) Destroy() {
+	panic("implement me")
+}
+
+type mockInvoker struct{}
+
+func (m *mockInvoker) GetURL() *common.URL {
+	panic("implement me")
+}
+
+func (m *mockInvoker) IsAvailable() bool {
+	panic("implement me")
+}
+
+func (m *mockInvoker) Destroy() {
+	panic("implement me")
+}
+
+func (m *mockInvoker) Invoke(context.Context, protocol.Invocation) protocol.Result {
+	// for getMetadataInfo and ServiceInstancesChangedListenerImpl onEvent
+	serviceInfo := &common.ServiceInfo{ServiceKey: "test", MatchKey: "test"}
+	services := make(map[string]*common.ServiceInfo)
+	services["test"] = serviceInfo
+	return &protocol.RPCResult{
+		Rest: &common.MetadataInfo{
+			Services: services,
+		},
+	}
+}