diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go
index 5ea9858214f16e53e72934a59853a04a0207fd6e..dc3902291c4017188506b1b8a5f2d3bcf454a609 100644
--- a/cluster/directory/base_directory.go
+++ b/cluster/directory/base_directory.go
@@ -41,7 +41,6 @@ type BaseDirectory struct {
 	url         *common.URL
 	destroyed   *atomic.Bool
 	mutex       sync.Mutex
-	once        sync.Once
 	routerChain router.Chain
 }
 
@@ -87,8 +86,6 @@ func (dir *BaseDirectory) SetRouters(routers []router.Router) {
 		}
 	}
 
-	dir.mutex.Lock()
-	defer dir.mutex.Unlock()
 	dir.routerChain.AddRouters(routers)
 }
 
diff --git a/cluster/directory/static_directory.go b/cluster/directory/static_directory.go
index b7757ea91e7156fceb47cf924732e22f576a7d1b..abe03db90acad0002be0671f784bb81e2931d42d 100644
--- a/cluster/directory/static_directory.go
+++ b/cluster/directory/static_directory.go
@@ -54,7 +54,9 @@ func (dir *staticDirectory) IsAvailable() bool {
 }
 
 func (dir *staticDirectory) List(invocation protocol.Invocation) []protocol.Invoker {
-	invokers := dir.invokers
+	l := len(dir.invokers)
+	invokers := make([]protocol.Invoker, l, l)
+	copy(invokers, dir.invokers)
 	routerChain := dir.RouterChain()
 
 	if routerChain == nil {
diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go
index 4ca596886f920e05b295f44ec95b86321592c8e4..d85fb3d0e246ae1ea24785e58feafd7b5beb3cc7 100644
--- a/cluster/router/chain/chain.go
+++ b/cluster/router/chain/chain.go
@@ -19,6 +19,7 @@ package chain
 
 import (
 	"sort"
+	"sync"
 )
 
 import (
@@ -42,11 +43,19 @@ type RouterChain struct {
 	// 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
+
+	mutex sync.RWMutex
 }
 
 func (c RouterChain) Route(invoker []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
 	finalInvokers := invoker
-	for _, r := range c.routers {
+	l := len(c.routers)
+	rs := make([]router.Router, l, l)
+	c.mutex.RLock()
+	copy(rs, c.routers)
+	c.mutex.RUnlock()
+
+	for _, r := range rs {
 		finalInvokers = r.Route(invoker, url, invocation)
 	}
 	return finalInvokers
@@ -56,6 +65,8 @@ func (c RouterChain) AddRouters(routers []router.Router) {
 	newRouters = append(newRouters, c.builtinRouters...)
 	newRouters = append(newRouters, routers...)
 	sortRouter(newRouters)
+	c.mutex.Lock()
+	defer c.mutex.Unlock()
 	c.routers = newRouters
 }