diff --git a/config_center/nacos/client.go b/config_center/nacos/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..d87ee74dda6b9692a4a31e252ad77d28240f5741
--- /dev/null
+++ b/config_center/nacos/client.go
@@ -0,0 +1,217 @@
+package nacos
+
+import (
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+import (
+	"github.com/nacos-group/nacos-sdk-go/clients"
+	"github.com/nacos-group/nacos-sdk-go/clients/config_client"
+	nacosconst "github.com/nacos-group/nacos-sdk-go/common/constant"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+)
+
+const logDir = "logs/nacos/log"
+
+// NacosClient Nacos client
+type NacosClient struct {
+	name       string
+	NacosAddrs []string
+	sync.Mutex // for Client
+	client     *config_client.IConfigClient
+	exit       chan struct{}
+	Timeout    time.Duration
+	once       sync.Once
+	onceClose  func()
+}
+
+// Client Get Client
+func (n *NacosClient) Client() *config_client.IConfigClient {
+	return n.client
+}
+
+// SetClient Set client
+func (n *NacosClient) SetClient(client *config_client.IConfigClient) {
+	n.Lock()
+	n.client = client
+	n.Unlock()
+}
+
+type option func(*options)
+
+type options struct {
+	nacosName string
+	client    *NacosClient
+}
+
+// WithNacosName Set nacos name
+func WithNacosName(name string) option {
+	return func(opt *options) {
+		opt.nacosName = name
+	}
+}
+
+// ValidateNacosClient Validate nacos client , if null then create it
+func ValidateNacosClient(container nacosClientFacade, opts ...option) error {
+	if container == nil {
+		return perrors.Errorf("container can not be null")
+	}
+	os := &options{}
+	for _, opt := range opts {
+		opt(os)
+	}
+
+	url := container.GetUrl()
+
+	if container.NacosClient() == nil {
+		//in dubbo ,every registry only connect one node ,so this is []string{r.Address}
+		timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT))
+		if err != nil {
+			logger.Errorf("timeout config %v is invalid ,err is %v",
+				url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT), err.Error())
+			return perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location)
+		}
+		nacosAddresses := strings.Split(url.Location, ",")
+		newClient, err := newNacosClient(os.nacosName, nacosAddresses, timeout)
+		if err != nil {
+			logger.Warnf("newNacosClient(name{%s}, nacos address{%v}, timeout{%d}) = error{%v}",
+				os.nacosName, url.Location, timeout.String(), err)
+			return perrors.WithMessagef(err, "newNacosClient(address:%+v)", url.Location)
+		}
+		container.SetNacosClient(newClient)
+	}
+
+	if container.NacosClient().Client() == nil {
+		svrConfList := []nacosconst.ServerConfig{}
+		for _, nacosAddr := range container.NacosClient().NacosAddrs {
+			split := strings.Split(nacosAddr, ":")
+			port, err := strconv.ParseUint(split[1], 10, 64)
+			if err != nil {
+				logger.Warnf("nacos addr port parse error ,error message is %v", err)
+				continue
+			}
+			svrconf := nacosconst.ServerConfig{
+				IpAddr: split[0],
+				Port:   port,
+			}
+			svrConfList = append(svrConfList, svrconf)
+		}
+
+		client, err := clients.CreateConfigClient(map[string]interface{}{
+			"serverConfigs": svrConfList,
+			"clientConfig": nacosconst.ClientConfig{
+				TimeoutMs:           uint64(int32(container.NacosClient().Timeout / time.Millisecond)),
+				ListenInterval:      10000,
+				NotLoadCacheAtStart: true,
+				LogDir:              logDir,
+			},
+		})
+
+		container.NacosClient().SetClient(&client)
+		if err != nil {
+			logger.Errorf("nacos create config client error:%v", err)
+		}
+	}
+
+	return perrors.WithMessagef(nil, "newNacosClient(address:%+v)", url.PrimitiveURL)
+}
+
+func newNacosClient(name string, nacosAddrs []string, timeout time.Duration) (*NacosClient, error) {
+	var (
+		err error
+		n   *NacosClient
+	)
+
+	n = &NacosClient{
+		name:       name,
+		NacosAddrs: nacosAddrs,
+		Timeout:    timeout,
+		exit:       make(chan struct{}),
+		onceClose: func() {
+			close(n.exit)
+		},
+	}
+
+	svrConfList := []nacosconst.ServerConfig{}
+	for _, nacosAddr := range n.NacosAddrs {
+		split := strings.Split(nacosAddr, ":")
+		port, err := strconv.ParseUint(split[1], 10, 64)
+		if err != nil {
+			logger.Warnf("convert port , source:%s , error:%v ", split[1], err)
+			continue
+		}
+		svrconf := nacosconst.ServerConfig{
+			IpAddr: split[0],
+			Port:   port,
+		}
+		svrConfList = append(svrConfList, svrconf)
+	}
+	client, err := clients.CreateConfigClient(map[string]interface{}{
+		"serverConfigs": svrConfList,
+		"clientConfig": nacosconst.ClientConfig{
+			TimeoutMs:           uint64(timeout / time.Millisecond),
+			ListenInterval:      20000,
+			NotLoadCacheAtStart: true,
+			LogDir:              logDir,
+		},
+	})
+	n.SetClient(&client)
+	if err != nil {
+		return nil, perrors.WithMessagef(err, "nacos clients.CreateConfigClient(nacosAddrs:%+v)", nacosAddrs)
+	}
+
+	return n, nil
+}
+
+// Done Get nacos client exit signal
+func (n *NacosClient) Done() <-chan struct{} {
+	return n.exit
+}
+
+func (n *NacosClient) stop() bool {
+	select {
+	case <-n.exit:
+		return true
+	default:
+		n.once.Do(n.onceClose)
+	}
+
+	return false
+}
+
+// NacosClientValid Get nacos client valid status
+func (n *NacosClient) NacosClientValid() bool {
+	select {
+	case <-n.exit:
+		return false
+	default:
+	}
+
+	valid := true
+	n.Lock()
+	if n.Client() == nil {
+		valid = false
+	}
+	n.Unlock()
+
+	return valid
+}
+
+// Close Close nacos client , then set null
+func (n *NacosClient) Close() {
+	if n == nil {
+		return
+	}
+
+	n.stop()
+	n.SetClient(nil)
+	logger.Warnf("nacosClient{name:%s, nacos addr:%s} exit now.", n.name, n.NacosAddrs)
+}
diff --git a/config_center/nacos/client_test.go b/config_center/nacos/client_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..47a05dec6674e995aa9e5bd177ef339b768aa740
--- /dev/null
+++ b/config_center/nacos/client_test.go
@@ -0,0 +1,31 @@
+package nacos
+
+import (
+	"strings"
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+)
+
+func Test_newNacosClient(t *testing.T) {
+	server := mockCommonNacosServer()
+	nacosURL := strings.ReplaceAll(server.URL, "http", "registry")
+	registryUrl, _ := common.NewURL(nacosURL)
+	c := &nacosDynamicConfiguration{
+		url:  &registryUrl,
+		done: make(chan struct{}),
+	}
+	err := ValidateNacosClient(c, WithNacosName(nacosClientName))
+	assert.NoError(t, err)
+	c.wg.Add(1)
+	go HandleClientRestart(c)
+	c.client.Close()
+	<-c.client.Done()
+	c.Destroy()
+}
diff --git a/config_center/nacos/facade.go b/config_center/nacos/facade.go
new file mode 100644
index 0000000000000000000000000000000000000000..fc83e14eac7fcc51025b54f6daff2553f309312c
--- /dev/null
+++ b/config_center/nacos/facade.go
@@ -0,0 +1,97 @@
+/*
+ * 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 nacos
+
+import (
+	"sync"
+	"time"
+)
+import (
+	"github.com/dubbogo/getty"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/logger"
+)
+
+const (
+	connDelay    = 3
+	maxFailTimes = 15
+)
+
+type nacosClientFacade interface {
+	NacosClient() *NacosClient
+	SetNacosClient(*NacosClient)
+	// WaitGroup for wait group control, zk client listener & zk client container
+	WaitGroup() *sync.WaitGroup
+	// GetDone For nacos client control	RestartCallBack() bool
+	GetDone() chan struct{}
+	common.Node
+}
+
+func timeSecondDuration(sec int) time.Duration {
+	return time.Duration(sec) * time.Second
+}
+
+// HandleClientRestart Restart client handler
+func HandleClientRestart(r nacosClientFacade) {
+	var (
+		err error
+
+		failTimes int
+	)
+
+	defer r.WaitGroup().Done()
+LOOP:
+	for {
+		select {
+		case <-r.GetDone():
+			logger.Warnf("(NacosProviderRegistry)reconnectNacosRegistry goroutine exit now...")
+			break LOOP
+			// re-register all services
+		case <-r.NacosClient().Done():
+			r.NacosClient().Close()
+			nacosName := r.NacosClient().name
+			nacosAddress := r.NacosClient().NacosAddrs
+			r.SetNacosClient(nil)
+
+			// Connect nacos until success.
+			failTimes = 0
+			for {
+				select {
+				case <-r.GetDone():
+					logger.Warnf("(NacosProviderRegistry)reconnectZkRegistry goroutine exit now...")
+					break LOOP
+				case <-getty.GetTimeWheel().After(timeSecondDuration(failTimes * connDelay)): // Prevent crazy reconnection nacos.
+				}
+				err = ValidateNacosClient(r, WithNacosName(nacosName))
+				logger.Infof("NacosProviderRegistry.validateNacosClient(nacosAddr{%s}) = error{%#v}",
+					nacosAddress, perrors.WithStack(err))
+				if err == nil {
+					break
+				}
+				failTimes++
+				if maxFailTimes <= failTimes {
+					failTimes = maxFailTimes
+				}
+			}
+		}
+	}
+}
diff --git a/config_center/nacos/factory.go b/config_center/nacos/factory.go
new file mode 100644
index 0000000000000000000000000000000000000000..3de91ea013df0c6bef8d70c741ff840ba3b77572
--- /dev/null
+++ b/config_center/nacos/factory.go
@@ -0,0 +1,43 @@
+/*
+ * 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 nacos
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/config_center"
+	"github.com/apache/dubbo-go/config_center/parser"
+)
+
+func init() {
+	extension.SetConfigCenterFactory("nacos", func() config_center.DynamicConfigurationFactory { return &nacosDynamicConfigurationFactory{} })
+}
+
+type nacosDynamicConfigurationFactory struct {
+}
+
+// GetDynamicConfiguration Get Configuration with URL
+func (f *nacosDynamicConfigurationFactory) GetDynamicConfiguration(url *common.URL) (config_center.DynamicConfiguration, error) {
+	dynamicConfiguration, err := newNacosDynamicConfiguration(url)
+	if err != nil {
+		return nil, err
+	}
+	dynamicConfiguration.SetParser(&parser.DefaultConfigurationParser{})
+	return dynamicConfiguration, err
+
+}
diff --git a/config_center/nacos/impl.go b/config_center/nacos/impl.go
new file mode 100644
index 0000000000000000000000000000000000000000..60ab89b003ff62016b9137223425c1051356975f
--- /dev/null
+++ b/config_center/nacos/impl.go
@@ -0,0 +1,166 @@
+/*
+ * 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 nacos
+
+import (
+	"sync"
+)
+
+import (
+	"github.com/nacos-group/nacos-sdk-go/vo"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config_center"
+	"github.com/apache/dubbo-go/config_center/parser"
+)
+
+const nacosClientName = "nacos config_center"
+
+type nacosDynamicConfiguration struct {
+	url          *common.URL
+	rootPath     string
+	wg           sync.WaitGroup
+	cltLock      sync.Mutex
+	done         chan struct{}
+	client       *NacosClient
+	keyListeners sync.Map
+	parser       parser.ConfigurationParser
+}
+
+func newNacosDynamicConfiguration(url *common.URL) (*nacosDynamicConfiguration, error) {
+	c := &nacosDynamicConfiguration{
+		rootPath: "/" + url.GetParam(constant.CONFIG_NAMESPACE_KEY, config_center.DEFAULT_GROUP) + "/config",
+		url:      url,
+		done:     make(chan struct{}),
+	}
+	err := ValidateNacosClient(c, WithNacosName(nacosClientName))
+	if err != nil {
+		logger.Errorf("nacos client start error ,error message is %v", err)
+		return nil, err
+	}
+	c.wg.Add(1)
+	go HandleClientRestart(c)
+	return c, err
+
+}
+
+// AddListener Add listener
+func (n *nacosDynamicConfiguration) AddListener(key string, listener config_center.ConfigurationListener, opions ...config_center.Option) {
+	n.addListener(key, listener)
+}
+
+// RemoveListener Remove listener
+func (n *nacosDynamicConfiguration) RemoveListener(key string, listener config_center.ConfigurationListener, opions ...config_center.Option) {
+	n.removeListener(key, listener)
+}
+
+//nacos distinguishes configuration files based on group and dataId. defalut group = "dubbo" and dataId = key
+func (n *nacosDynamicConfiguration) GetProperties(key string, opts ...config_center.Option) (string, error) {
+	return n.GetRule(key, opts...)
+}
+
+// GetInternalProperty Get properties value by key
+func (n *nacosDynamicConfiguration) GetInternalProperty(key string, opts ...config_center.Option) (string, error) {
+	return n.GetProperties(key, opts...)
+}
+
+// GetRule Get router rule
+func (n *nacosDynamicConfiguration) GetRule(key string, opts ...config_center.Option) (string, error) {
+	tmpOpts := &config_center.Options{}
+	for _, opt := range opts {
+		opt(tmpOpts)
+	}
+	content, err := (*n.client.Client()).GetConfig(vo.ConfigParam{
+		DataId: key,
+		Group:  tmpOpts.Group,
+	})
+	if err != nil {
+		return "", perrors.WithStack(err)
+	} else {
+		return string(content), nil
+	}
+}
+
+// Parser Get Parser
+func (n *nacosDynamicConfiguration) Parser() parser.ConfigurationParser {
+	return n.parser
+}
+
+// SetParser Set Parser
+func (n *nacosDynamicConfiguration) SetParser(p parser.ConfigurationParser) {
+	n.parser = p
+}
+
+// NacosClient Get Nacos Client
+func (n *nacosDynamicConfiguration) NacosClient() *NacosClient {
+	return n.client
+}
+
+// SetNacosClient Set Nacos Client
+func (n *nacosDynamicConfiguration) SetNacosClient(client *NacosClient) {
+	n.cltLock.Lock()
+	n.client = client
+	n.cltLock.Unlock()
+}
+
+// WaitGroup for wait group control, zk client listener & zk client container
+func (n *nacosDynamicConfiguration) WaitGroup() *sync.WaitGroup {
+	return &n.wg
+}
+
+// GetDone For nacos client control	RestartCallBack() bool
+func (n *nacosDynamicConfiguration) GetDone() chan struct{} {
+	return n.done
+}
+
+// GetUrl Get Url
+func (n *nacosDynamicConfiguration) GetUrl() common.URL {
+	return *n.url
+}
+
+// Destroy Destroy configuration instance
+func (n *nacosDynamicConfiguration) Destroy() {
+	close(n.done)
+	n.wg.Wait()
+	n.closeConfigs()
+}
+
+// IsAvailable Get available status
+func (n *nacosDynamicConfiguration) IsAvailable() bool {
+	select {
+	case <-n.done:
+		return false
+	default:
+		return true
+	}
+}
+
+func (r *nacosDynamicConfiguration) closeConfigs() {
+	r.cltLock.Lock()
+	client := r.client
+	r.client = nil
+	r.cltLock.Unlock()
+	// Close the old client first to close the tmp node
+	client.Close()
+	logger.Infof("begin to close provider nacos client")
+}
diff --git a/config_center/nacos/impl_test.go b/config_center/nacos/impl_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..07bf8638d2d80123545db02c16544001c06e335b
--- /dev/null
+++ b/config_center/nacos/impl_test.go
@@ -0,0 +1,117 @@
+/*
+ * 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 nacos
+
+import (
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/config_center"
+	"github.com/apache/dubbo-go/config_center/parser"
+)
+
+// run mock config server
+func runMockConfigServer(configHandler func(http.ResponseWriter, *http.Request),
+	configListenHandler func(http.ResponseWriter, *http.Request)) *httptest.Server {
+	uriHandlerMap := make(map[string]func(http.ResponseWriter, *http.Request), 0)
+
+	uriHandlerMap["/nacos/v1/cs/configs"] = configHandler
+	uriHandlerMap["/nacos/v1/cs/configs/listener"] = configListenHandler
+
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		uri := r.RequestURI
+		for path, handler := range uriHandlerMap {
+			if uri == path {
+				handler(w, r)
+				break
+			}
+		}
+	}))
+
+	return ts
+}
+
+func mockCommonNacosServer() *httptest.Server {
+	return runMockConfigServer(func(writer http.ResponseWriter, request *http.Request) {
+		data := `
+	dubbo.service.com.ikurento.user.UserProvider.cluster=failback
+	dubbo.service.com.ikurento.user.UserProvider.protocol=myDubbo1
+	dubbo.protocols.myDubbo.port=20000
+	dubbo.protocols.myDubbo.name=dubbo
+`
+		fmt.Fprintf(writer, "%s", data)
+	}, func(writer http.ResponseWriter, request *http.Request) {
+		data := `dubbo.properties%02dubbo%02dubbo.service.com.ikurento.user.UserProvider.cluster=failback`
+		fmt.Fprintf(writer, "%s", data)
+	})
+}
+
+func initNacosData(t *testing.T) (*nacosDynamicConfiguration, error) {
+	server := mockCommonNacosServer()
+	nacosURL := strings.ReplaceAll(server.URL, "http", "registry")
+	regurl, _ := common.NewURL(nacosURL)
+	nacosConfiguration, err := newNacosDynamicConfiguration(&regurl)
+	assert.NoError(t, err)
+
+	nacosConfiguration.SetParser(&parser.DefaultConfigurationParser{})
+
+	return nacosConfiguration, err
+}
+
+func Test_GetConfig(t *testing.T) {
+	nacos, err := initNacosData(t)
+	assert.NoError(t, err)
+	configs, err := nacos.GetProperties("dubbo.properties", config_center.WithGroup("dubbo"))
+	_, err = nacos.Parser().Parse(configs)
+	assert.NoError(t, err)
+}
+
+func Test_AddListener(t *testing.T) {
+	nacos, err := initNacosData(t)
+	assert.NoError(t, err)
+	listener := &mockDataListener{}
+	time.Sleep(time.Second * 2)
+	nacos.AddListener("dubbo.properties", listener)
+	listener.wg.Add(1)
+	listener.wg.Wait()
+}
+
+func Test_RemoveListener(t *testing.T) {
+	//TODO not supported in current go_nacos_sdk version
+}
+
+type mockDataListener struct {
+	wg    sync.WaitGroup
+	event string
+}
+
+func (l *mockDataListener) Process(configType *config_center.ConfigChangeEvent) {
+	l.wg.Done()
+	l.event = configType.Key
+}
diff --git a/config_center/nacos/listener.go b/config_center/nacos/listener.go
new file mode 100644
index 0000000000000000000000000000000000000000..25c586586c7202e42ff44d6104e8132961add25a
--- /dev/null
+++ b/config_center/nacos/listener.go
@@ -0,0 +1,62 @@
+/*
+ * 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 nacos
+
+import (
+	"context"
+)
+
+import (
+	"github.com/nacos-group/nacos-sdk-go/vo"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config_center"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+func callback(listener config_center.ConfigurationListener, namespace, group, dataId, data string) {
+	listener.Process(&config_center.ConfigChangeEvent{Key: dataId, Value: data, ConfigType: remoting.EventTypeUpdate})
+}
+
+func (l *nacosDynamicConfiguration) addListener(key string, listener config_center.ConfigurationListener) {
+	_, loaded := l.keyListeners.Load(key)
+	if !loaded {
+		_, cancel := context.WithCancel(context.Background())
+		err := (*l.client.Client()).ListenConfig(vo.ConfigParam{
+			DataId: key,
+			Group:  "dubbo",
+			OnChange: func(namespace, group, dataId, data string) {
+				go callback(listener, namespace, group, dataId, data)
+			},
+		})
+		logger.Errorf("nacos : listen config fail, error:%v ", err)
+		newListener := make(map[config_center.ConfigurationListener]context.CancelFunc)
+		newListener[listener] = cancel
+		l.keyListeners.Store(key, newListener)
+	} else {
+		// TODO check goroutine alive, but this version of go_nacos_sdk is not support.
+		logger.Infof("profile:%s. this profile is already listening", key)
+	}
+}
+
+func (l *nacosDynamicConfiguration) removeListener(key string, listener config_center.ConfigurationListener) {
+	// TODO: not supported in current go_nacos_sdk version
+	logger.Warn("not supported in current go_nacos_sdk version")
+}
diff --git a/protocol/dubbo/pool.go b/protocol/dubbo/pool.go
index 2df1c6935305e0d70635613f509021e5b9203833..9d381585b56ec439f8ebb8938109baf47bb502b2 100644
--- a/protocol/dubbo/pool.go
+++ b/protocol/dubbo/pool.go
@@ -360,6 +360,13 @@ func (p *gettyRPCClientPool) put(conn *gettyRPCClient) {
 		return
 	}
 
+	// check whether @conn has existed in p.conns or not.
+	for i := range p.conns {
+		if p.conns[i] == conn {
+			return
+		}
+	}
+
 	if len(p.conns) >= p.size {
 		// delete @conn from client pool
 		// p.remove(conn)