diff --git a/registry/protocol/protocol.go b/registry/protocol/protocol.go
index 534a4b945965f332e49ff343557fa20355921454..ffdb2753d6bfa0712b8fb9c962c8433a5c281083 100644
--- a/registry/protocol/protocol.go
+++ b/registry/protocol/protocol.go
@@ -338,10 +338,10 @@ func setProviderUrl(regURL *common.URL, providerURL *common.URL) {
 }
 
 func GetProtocol() protocol.Protocol {
-	if regProtocol != nil {
-		return regProtocol
+	if regProtocol == nil {
+		regProtocol = newRegistryProtocol()
 	}
-	return newRegistryProtocol()
+	return regProtocol
 }
 
 type wrappedInvoker struct {
diff --git a/registry/protocol/protocol_test.go b/registry/protocol/protocol_test.go
index 0c19da59df6e4fd2f663f9e8d541165fe26c3ffa..761d14006680a3e0f3a111458d32155b19c26968 100644
--- a/registry/protocol/protocol_test.go
+++ b/registry/protocol/protocol_test.go
@@ -291,3 +291,8 @@ func TestExportWithApplicationConfig(t *testing.T) {
 	v2, _ := regProtocol.bounds.Load(getCacheKey(newUrl))
 	assert.NotNil(t, v2)
 }
+
+func TestGetProtocol(t *testing.T) {
+	singleton := GetProtocol()
+	assert.True(t, singleton == GetProtocol())
+}
diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go
index 857421f07706d6bdfec5a3ec21ba674627633458..c25028d58f32f4028779fd6c050e60eef2bd7bd5 100644
--- a/registry/zookeeper/listener.go
+++ b/registry/zookeeper/listener.go
@@ -109,7 +109,13 @@ func (l *RegistryConfigurationListener) Next() (*registry.ServiceEvent, error) {
 	}
 }
 func (l *RegistryConfigurationListener) Close() {
-	l.registry.wg.Done()
+	if l.registry.IsAvailable() {
+		/**
+		 * if the registry is not available, it means that the registry has been destroy
+		 * so we don't need to call Done(), or it will cause the negative count panic for registry.wg
+		 */
+		l.registry.wg.Done()
+	}
 }
 
 func (l *RegistryConfigurationListener) valid() bool {