diff --git a/before_ut.bat b/before_ut.bat
index a10df71a7eeb2eadb9d86574dc374b14a4f74e05..5296d0f8769b7b9f521f82e68bf3b10f4b5d16b4 100644
--- a/before_ut.bat
+++ b/before_ut.bat
@@ -1,3 +1,19 @@
+::
+::  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.
+
 set zkJar=zookeeper-3.4.9-fatjar.jar
 md remoting\zookeeper\zookeeper-4unittest\contrib\fatjar config_center\zookeeper\zookeeper-4unittest\contrib\fatjar registry\zookeeper\zookeeper-4unittest\contrib\fatjar
 curl -L https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/%zkJar% -o remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar%
diff --git a/before_ut.sh b/before_ut.sh
index 7acee76ce5991ac1d06bff6a6325f083904f10b9..323173bcc64c3cbe9916747e10dd3ea8538457ea 100644
--- a/before_ut.sh
+++ b/before_ut.sh
@@ -1,3 +1,20 @@
+#
+#  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.
+
+
 mkdir -p remoting/zookeeper/zookeeper-4unittest/contrib/fatjar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar registry/zookeeper/zookeeper-4unittest/contrib/fatjar
 wget -P "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar" https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar
 cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/
diff --git a/common/constant/default.go b/common/constant/default.go
index cb6d68af0561d44f4306f16973a89759c9a9ac37..cb66f5f0ab1cd917278b71103f34a341a1e598d6 100644
--- a/common/constant/default.go
+++ b/common/constant/default.go
@@ -46,8 +46,8 @@ const (
 const (
 	DEFAULT_KEY               = "default"
 	PREFIX_DEFAULT_KEY        = "default."
-	DEFAULT_SERVICE_FILTERS   = "echo,token,accesslog,tps,execute"
-	DEFAULT_REFERENCE_FILTERS = ""
+	DEFAULT_SERVICE_FILTERS   = "echo,token,accesslog,tps,execute,pshutdown"
+	DEFAULT_REFERENCE_FILTERS = "cshutdown"
 	GENERIC_REFERENCE_FILTERS = "generic"
 	GENERIC                   = "$invoke"
 	ECHO                      = "$echo"
diff --git a/common/constant/key.go b/common/constant/key.go
index 0c0c91f39e3134eeebe83524850e10f24f5bb1fb..6d6e322f15900336a13813547a99021a356e9bcd 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -71,6 +71,8 @@ const (
 	EXECUTE_LIMIT_KEY                      = "execute.limit"
 	DEFAULT_EXECUTE_LIMIT                  = "-1"
 	EXECUTE_REJECTED_EXECUTION_HANDLER_KEY = "execute.limit.rejected.handler"
+	PROVIDER_SHUTDOWN_FILTER               = "pshutdown"
+	CONSUMER_SHUTDOWN_FILTER               = "cshutdown"
 )
 
 const (
@@ -115,6 +117,7 @@ const (
 	ProtocolConfigPrefix       = "dubbo.protocols."
 	ProviderConfigPrefix       = "dubbo.provider."
 	ConsumerConfigPrefix       = "dubbo.consumer."
+	ShutdownConfigPrefix       = "dubbo.shutdown."
 )
 
 const (
diff --git a/common/extension/graceful_shutdown.go b/common/extension/graceful_shutdown.go
new file mode 100644
index 0000000000000000000000000000000000000000..c8807fcc28c18c1a6fddb4e97708e9b0d5cda243
--- /dev/null
+++ b/common/extension/graceful_shutdown.go
@@ -0,0 +1,53 @@
+/*
+ * 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 extension
+
+import (
+	"container/list"
+)
+
+var (
+	customShutdownCallbacks = list.New()
+)
+
+/**
+ * you should not make any assumption about the order.
+ * For example, if you have more than one callbacks, and you wish the order is:
+ * callback1()
+ * callback2()
+ * ...
+ * callbackN()
+ * Then you should put then together:
+ * func callback() {
+ *     callback1()
+ *     callback2()
+ *     ...
+ *     callbackN()
+ * }
+ * I think the order of custom callbacks should be decided by the users.
+ * Even though I can design a mechanism to support the ordered custom callbacks,
+ * the benefit of that mechanism is low.
+ * And it may introduce much complication for another users.
+ */
+func AddCustomShutdownCallback(callback func()) {
+	customShutdownCallbacks.PushBack(callback)
+}
+
+func GetAllCustomShutdownCallbacks() *list.List {
+	return customShutdownCallbacks
+}
diff --git a/config/base_config_test.go b/config/base_config_test.go
index 54def2ae1bc60135619d86be8939710589df5b13..ab2769578072387e4686593f3c2c10fb8e49731d 100644
--- a/config/base_config_test.go
+++ b/config/base_config_test.go
@@ -40,6 +40,7 @@ func Test_refresh(t *testing.T) {
 	mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
 	mockMap["dubbo.consumer.check"] = "false"
 	mockMap["dubbo.application.name"] = "dubbo"
+	mockMap["dubbo.shutdown.timeout"] = "12s"
 
 	config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
 
@@ -114,6 +115,13 @@ func Test_refresh(t *testing.T) {
 				},
 			},
 		},
+		ShutdownConfig: &ShutdownConfig{
+			Timeout:              "12s",
+			StepTimeout:          "2s",
+			RejectRequestHandler: "mock",
+			RejectRequest:        false,
+			RequestsFinished:     false,
+		},
 	}
 
 	c.SetFatherConfig(father)
diff --git a/config/config_loader.go b/config/config_loader.go
index b737d3f233700f596469cfd678aa7ae7f9a82b85..414bb479025c5d6111a6373fa2626f21ffa73ef0 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -149,6 +149,8 @@ func Load() {
 			}
 		}
 	}
+	// init the shutdown callback
+	GracefulShutdownInit()
 }
 
 // get rpc service for consumer
diff --git a/config/consumer_config.go b/config/consumer_config.go
index b1ebdd5d8e082bf836071460e2a330632e07335c..72f60b5f77b9b9cc633d8939713c0eb93563deac 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -52,11 +52,12 @@ type ConsumerConfig struct {
 	ProxyFactory    string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"`
 	Check           *bool  `yaml:"check"  json:"check,omitempty" property:"check"`
 
-	Registry     *RegistryConfig             `yaml:"registry" json:"registry,omitempty" property:"registry"`
-	Registries   map[string]*RegistryConfig  `yaml:"registries" json:"registries,omitempty" property:"registries"`
-	References   map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"`
-	ProtocolConf interface{}                 `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf"`
-	FilterConf   interface{}                 `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" `
+	Registry       *RegistryConfig             `yaml:"registry" json:"registry,omitempty" property:"registry"`
+	Registries     map[string]*RegistryConfig  `yaml:"registries" json:"registries,omitempty" property:"registries"`
+	References     map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"`
+	ProtocolConf   interface{}                 `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf"`
+	FilterConf     interface{}                 `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" `
+	ShutdownConfig *ShutdownConfig             `yaml:"shutdown_conf" json:"shutdown_conf,omitempty" property:"shutdown_conf" `
 }
 
 func (c *ConsumerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
diff --git a/config/graceful_shutdown.go b/config/graceful_shutdown.go
new file mode 100644
index 0000000000000000000000000000000000000000..0b39d111503377df318b4cfbf6243126183735d9
--- /dev/null
+++ b/config/graceful_shutdown.go
@@ -0,0 +1,231 @@
+/*
+ * 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 config
+
+import (
+	"os"
+	"os/signal"
+	"runtime/debug"
+	"syscall"
+	"time"
+)
+
+import (
+	"github.com/dubbogo/gost/container/gxset"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+)
+
+/*
+ * The key point is that find out the signals to handle.
+ * The most important documentation is https://golang.org/pkg/os/signal/
+ * From this documentation, we can know that:
+ * 1. The signals SIGKILL and SIGSTOP may not be caught by signal package;
+ * 2. SIGHUP, SIGINT, or SIGTERM signal causes the program to exit
+ * 3. SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal causes the program to exit with a stack dump
+ * 4. The invocation of Notify(signal...) will disable the default behavior of those signals.
+ *
+ * So the signals SIGKILL, SIGSTOP, SIGHUP, SIGINT, SIGTERM, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, SIGSYS
+ * should be processed.
+ * syscall.SIGEMT cannot be found in CI
+ * It's seems that the Unix/Linux does not have the signal SIGSTKFLT. https://github.com/golang/go/issues/33381
+ * So this signal will be ignored.
+ *
+ */
+
+func GracefulShutdownInit() {
+
+	signals := make(chan os.Signal, 1)
+
+	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP,
+		syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP,
+		syscall.SIGABRT, syscall.SIGSYS,
+	)
+
+	go func() {
+		select {
+		case sig := <-signals:
+			logger.Infof("get signal %s, application will shutdown.", sig)
+			// gracefulShutdownOnce.Do(func() {
+			BeforeShutdown()
+
+			switch sig {
+			// those signals' original behavior is exit with dump ths stack, so we try to keep the behavior
+			case syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP,
+				syscall.SIGABRT, syscall.SIGSYS:
+				debug.WriteHeapDump(os.Stdout.Fd())
+			default:
+				time.AfterFunc(totalTimeout(), func() {
+					logger.Warn("Shutdown gracefully timeout, application will shutdown immediately. ")
+					os.Exit(0)
+				})
+			}
+			os.Exit(0)
+		}
+	}()
+}
+
+func BeforeShutdown() {
+
+	destroyAllRegistries()
+	// waiting for a short time so that the clients have enough time to get the notification that server shutdowns
+	// The value of configuration depends on how long the clients will get notification.
+	waitAndAcceptNewRequests()
+
+	// reject the new request, but keeping waiting for accepting requests
+	waitForReceivingRequests()
+
+	// we fetch the protocols from Consumer.References. Consumer.ProtocolConfig doesn't contains all protocol, like jsonrpc
+	consumerProtocols := getConsumerProtocols()
+
+	// If this application is not the provider, it will do nothing
+	destroyProviderProtocols(consumerProtocols)
+
+	// reject sending the new request, and waiting for response of sending requests
+	waitForSendingRequests()
+
+	// If this application is not the consumer, it will do nothing
+	destroyConsumerProtocols(consumerProtocols)
+
+	logger.Info("Graceful shutdown --- Execute the custom callbacks.")
+	customCallbacks := extension.GetAllCustomShutdownCallbacks()
+	for callback := customCallbacks.Front(); callback != nil; callback = callback.Next() {
+		callback.Value.(func())()
+	}
+}
+
+func destroyAllRegistries() {
+	logger.Info("Graceful shutdown --- Destroy all registries. ")
+	registryProtocol := extension.GetProtocol(constant.REGISTRY_KEY)
+	registryProtocol.Destroy()
+}
+
+func destroyConsumerProtocols(consumerProtocols *gxset.HashSet) {
+	logger.Info("Graceful shutdown --- Destroy consumer's protocols. ")
+	for name := range consumerProtocols.Items {
+		extension.GetProtocol(name.(string)).Destroy()
+	}
+}
+
+/**
+ * destroy the provider's protocol.
+ * if the protocol is consumer's protocol too, we will keep it.
+ */
+func destroyProviderProtocols(consumerProtocols *gxset.HashSet) {
+
+	logger.Info("Graceful shutdown --- Destroy provider's protocols. ")
+
+	if providerConfig == nil || providerConfig.Protocols == nil {
+		return
+	}
+
+	for _, protocol := range providerConfig.Protocols {
+
+		// the protocol is the consumer's protocol too, we can not destroy it.
+		if consumerProtocols.Contains(protocol.Name) {
+			continue
+		}
+		extension.GetProtocol(protocol.Name).Destroy()
+	}
+}
+
+func waitAndAcceptNewRequests() {
+
+	logger.Info("Graceful shutdown --- Keep waiting and accept new requests for a short time. ")
+	if providerConfig == nil || providerConfig.ShutdownConfig == nil {
+		return
+	}
+
+	timeout := providerConfig.ShutdownConfig.GetStepTimeout()
+
+	// ignore this step
+	if timeout < 0 {
+		return
+	}
+	time.Sleep(timeout)
+}
+
+// for provider. It will wait for processing receiving requests
+func waitForReceivingRequests() {
+	logger.Info("Graceful shutdown --- Keep waiting until accepting requests finish or timeout. ")
+	if providerConfig == nil || providerConfig.ShutdownConfig == nil {
+		// ignore this step
+		return
+	}
+	waitingProcessedTimeout(providerConfig.ShutdownConfig)
+}
+
+// for consumer. It will wait for the response of sending requests
+func waitForSendingRequests() {
+	logger.Info("Graceful shutdown --- Keep waiting until sending requests getting response or timeout ")
+	if consumerConfig == nil || consumerConfig.ShutdownConfig == nil {
+		// ignore this step
+		return
+	}
+	waitingProcessedTimeout(consumerConfig.ShutdownConfig)
+}
+
+func waitingProcessedTimeout(shutdownConfig *ShutdownConfig) {
+	timeout := shutdownConfig.GetStepTimeout()
+	if timeout <= 0 {
+		return
+	}
+	start := time.Now()
+
+	for time.Now().After(start.Add(timeout)) && !shutdownConfig.RequestsFinished {
+		// sleep 10 ms and then we check it again
+		time.Sleep(10 * time.Millisecond)
+	}
+}
+
+func totalTimeout() time.Duration {
+	var providerShutdown time.Duration
+	if providerConfig != nil && providerConfig.ShutdownConfig != nil {
+		providerShutdown = providerConfig.ShutdownConfig.GetTimeout()
+	}
+
+	var consumerShutdown time.Duration
+	if consumerConfig != nil && consumerConfig.ShutdownConfig != nil {
+		consumerShutdown = consumerConfig.ShutdownConfig.GetTimeout()
+	}
+
+	var timeout = providerShutdown
+	if consumerShutdown > providerShutdown {
+		timeout = consumerShutdown
+	}
+	return timeout
+}
+
+/*
+ * we can not get the protocols from consumerConfig because some protocol don't have configuration, like jsonrpc.
+ */
+func getConsumerProtocols() *gxset.HashSet {
+	result := gxset.NewSet()
+	if consumerConfig == nil || consumerConfig.References == nil {
+		return result
+	}
+
+	for _, reference := range consumerConfig.References {
+		result.Add(reference.Protocol)
+	}
+	return result
+}
diff --git a/config/graceful_shutdown_config.go b/config/graceful_shutdown_config.go
new file mode 100644
index 0000000000000000000000000000000000000000..df55728565f6cf14ce4357f8c9c7927c30d80e40
--- /dev/null
+++ b/config/graceful_shutdown_config.go
@@ -0,0 +1,82 @@
+/*
+ * 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 config
+
+import (
+	"time"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+)
+
+const (
+	defaultTimeout     = 60 * time.Second
+	defaultStepTimeout = 10 * time.Second
+)
+
+type ShutdownConfig struct {
+	/*
+	 * Total timeout. Even though we don't release all resources,
+	 * the application will shutdown if the costing time is over this configuration. The unit is ms.
+	 * default value is 60 * 1000 ms = 1 minutes
+	 * In general, it should be bigger than 3 * StepTimeout.
+	 */
+	Timeout string `default:"60s" yaml:"timeout" json:"timeout,omitempty" property:"timeout"`
+	/*
+	 * the timeout on each step. You should evaluate the response time of request
+	 * and the time that client noticed that server shutdown.
+	 * For example, if your client will received the notification within 10s when you start to close server,
+	 * and the 99.9% requests will return response in 2s, so the StepTimeout will be bigger than(10+2) * 1000ms,
+	 * maybe (10 + 2*3) * 1000ms is a good choice.
+	 */
+	StepTimeout string `default:"10s" yaml:"step_timeout" json:"step.timeout,omitempty" property:"step.timeout"`
+	// when we try to shutdown the application, 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"`
+	// true -> new request will be rejected.
+	RejectRequest bool
+
+	// true -> all requests had been processed. In provider side it means that all requests are returned response to clients
+	// In consumer side, it means that all requests getting response from servers
+	RequestsFinished bool
+}
+
+func (config *ShutdownConfig) Prefix() string {
+	return constant.ShutdownConfigPrefix
+}
+
+func (config *ShutdownConfig) GetTimeout() time.Duration {
+	result, err := time.ParseDuration(config.Timeout)
+	if err != nil {
+		logger.Errorf("The Timeout configuration is invalid: %s, and we will use the default value: %s, err: %v",
+			config.Timeout, defaultTimeout.String(), err)
+		return defaultTimeout
+	}
+	return result
+}
+
+func (config *ShutdownConfig) GetStepTimeout() time.Duration {
+	result, err := time.ParseDuration(config.StepTimeout)
+	if err != nil {
+		logger.Errorf("The StepTimeout configuration is invalid: %s, and we will use the default value: %s, err: %v",
+			config.StepTimeout, defaultStepTimeout.String(), err)
+		return defaultStepTimeout
+	}
+	return result
+}
diff --git a/config/graceful_shutdown_config_test.go b/config/graceful_shutdown_config_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..583ed70b838a8271a47e180ee3c6eb32cbb46984
--- /dev/null
+++ b/config/graceful_shutdown_config_test.go
@@ -0,0 +1,49 @@
+/*
+ * 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 config
+
+import (
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+func TestShutdownConfig_GetTimeout(t *testing.T) {
+	config := ShutdownConfig{}
+	assert.False(t, config.RejectRequest)
+	assert.False(t, config.RequestsFinished)
+
+	config = ShutdownConfig{
+		Timeout:     "12x",
+		StepTimeout: "34a",
+	}
+
+	assert.Equal(t, 60*time.Second, config.GetTimeout())
+	assert.Equal(t, 10*time.Second, config.GetStepTimeout())
+
+	config = ShutdownConfig{
+		Timeout:     "34ms",
+		StepTimeout: "79ms",
+	}
+
+	assert.Equal(t, 34*time.Millisecond, config.GetTimeout())
+	assert.Equal(t, 79*time.Millisecond, config.GetStepTimeout())
+}
diff --git a/config/graceful_shutdown_test.go b/config/graceful_shutdown_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..de203572c76281d221181dea90b0f31b43038de6
--- /dev/null
+++ b/config/graceful_shutdown_test.go
@@ -0,0 +1,99 @@
+/*
+ * 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 config
+
+import (
+	"testing"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+func TestGracefulShutdownInit(t *testing.T) {
+	GracefulShutdownInit()
+}
+
+func TestBeforeShutdown(t *testing.T) {
+	extension.SetProtocol("registry", func() protocol.Protocol {
+		return &mockRegistryProtocol{}
+	})
+	extension.SetProtocol(constant.DUBBO, func() protocol.Protocol {
+		return &mockRegistryProtocol{}
+	})
+
+	extension.SetProtocol("mock", func() protocol.Protocol {
+		return &mockRegistryProtocol{}
+	})
+
+	// protocolConfigs := make(map[interface{}]interface{}, 16)
+	consumerReferences := map[string]*ReferenceConfig{}
+	consumerReferences[constant.DUBBO] = &ReferenceConfig{
+		Protocol: constant.DUBBO,
+	}
+
+	// without configuration
+	BeforeShutdown()
+
+	consumerConfig = &ConsumerConfig{
+		References: consumerReferences,
+		ShutdownConfig: &ShutdownConfig{
+			Timeout:     "1",
+			StepTimeout: "1s",
+		}}
+
+	providerProtocols := map[string]*ProtocolConfig{}
+	providerProtocols[constant.DUBBO] = &ProtocolConfig{
+		Name: constant.DUBBO,
+	}
+
+	providerProtocols["mock"] = &ProtocolConfig{
+		Name: "mock",
+	}
+
+	providerConfig = &ProviderConfig{
+		ShutdownConfig: &ShutdownConfig{
+			Timeout:     "1",
+			StepTimeout: "1s",
+		},
+		Protocols: providerProtocols,
+	}
+	// test destroy protocol
+	BeforeShutdown()
+
+	providerConfig = &ProviderConfig{
+		ShutdownConfig: &ShutdownConfig{
+			Timeout:     "1",
+			StepTimeout: "-1s",
+		},
+		Protocols: providerProtocols,
+	}
+
+	consumerConfig = &ConsumerConfig{
+		References: consumerReferences,
+		ShutdownConfig: &ShutdownConfig{
+			Timeout:     "1",
+			StepTimeout: "-1s",
+		},
+	}
+
+	// test ignore steps
+	BeforeShutdown()
+}
diff --git a/config/provider_config.go b/config/provider_config.go
index 00faa1d0ab1b65a7a39d7d3548e5b89b0f250aba..0fed44c81b124cd40825695981a5394c273203fa 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -49,6 +49,7 @@ type ProviderConfig struct {
 	Protocols         map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"`
 	ProtocolConf      interface{}                `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf" `
 	FilterConf        interface{}                `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" `
+	ShutdownConfig    *ShutdownConfig            `yaml:"shutdown_conf" json:"shutdown_conf,omitempty" property:"shutdown_conf" `
 }
 
 func (c *ProviderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
@@ -106,6 +107,7 @@ func ProviderInit(confProFile string) error {
 	}
 
 	logger.Debugf("provider config{%#v}\n", providerConfig)
+
 	return nil
 }
 
diff --git a/config/provider_config_test.go b/config/provider_config_test.go
index db4b5f9906efb25cdb0ad8bf91f412f4510f5af5..e8a9c1f7a730f79e5bf92e1d7dd2e42b969cb0f3 100644
--- a/config/provider_config_test.go
+++ b/config/provider_config_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 config
 
 import (
diff --git a/config/testdata/consumer_config.yml b/config/testdata/consumer_config.yml
index 9fd50bb4d35a40d8532c9a644a86ad6834f8e89b..f44ea449fd16235050f6a7ba7823a87e24791780 100644
--- a/config/testdata/consumer_config.yml
+++ b/config/testdata/consumer_config.yml
@@ -49,6 +49,10 @@ references:
         "soa.com.ikurento.user.UserProvider"
       "forks": 5
 
+shutdown_conf:
+  timeout: 60s
+  step_timeout: 10s
+
 protocol_conf:
   dubbo:
     reconnect_interval: 0
diff --git a/config/testdata/consumer_config_with_configcenter.yml b/config/testdata/consumer_config_with_configcenter.yml
index 0550cc89741b6a490aaba9ff8906d7dda1b3ed49..ebe56fa93f9f5728aa365ee5b7a99b6bb5857a8e 100644
--- a/config/testdata/consumer_config_with_configcenter.yml
+++ b/config/testdata/consumer_config_with_configcenter.yml
@@ -17,6 +17,10 @@ references:
       - name: "GetUser"
         retries: "3"
 
+shutdown_conf:
+  timeout: 60s
+  step_timeout: 10s
+
 protocol_conf:
   dubbo:
     reconnect_interval: 0
diff --git a/config/testdata/consumer_config_withoutProtocol.yml b/config/testdata/consumer_config_withoutProtocol.yml
index 5e57c7ddf6e82152e4f207b2d06df1443766717c..32bad8b91db3fac9c026fca36c5dc3b84f4c3fc9 100644
--- a/config/testdata/consumer_config_withoutProtocol.yml
+++ b/config/testdata/consumer_config_withoutProtocol.yml
@@ -48,6 +48,10 @@ references:
         "soa.com.ikurento.user.UserProvider"
       "forks": 5
 
+shutdown_conf:
+  timeout: 60s
+  step_timeout: 10s
+
 protocol_conf:
   dubbo:
     reconnect_interval: 0
diff --git a/config/testdata/provider_config.yml b/config/testdata/provider_config.yml
index 080feb7dcd1cccd06ae436b2854b2531177d23e3..7c46f9101aa9a6ecb88a92953dfcec28dda4e0ff 100644
--- a/config/testdata/provider_config.yml
+++ b/config/testdata/provider_config.yml
@@ -71,6 +71,10 @@ protocols:
   #    ip: "127.0.0.1"
   #    port: 20001
 
+shutdown_conf:
+  timeout: 60s
+  step_timeout: 10s
+
 protocol_conf:
   dubbo:
     session_number: 700
diff --git a/config/testdata/provider_config_withoutProtocol.yml b/config/testdata/provider_config_withoutProtocol.yml
index 2f65868d4948db9a8b99c500014ea1307569d86f..532d3005aa351820bd540b31e2721dc2a0b5c6ed 100644
--- a/config/testdata/provider_config_withoutProtocol.yml
+++ b/config/testdata/provider_config_withoutProtocol.yml
@@ -51,6 +51,10 @@ protocols:
   #    ip: "127.0.0.1"
   #    port: 20001
 
+shutdown_conf:
+  timeout: 60s
+  step_timeout: 10s
+
 protocol_conf:
   dubbo:
     session_number: 700
diff --git a/dubbogo.png b/dubbogo.png
deleted file mode 100644
index 2cac434091276df102c3ae405c09621b8d8926ef..0000000000000000000000000000000000000000
Binary files a/dubbogo.png and /dev/null differ
diff --git a/filter/impl/graceful_shutdown_filter.go b/filter/impl/graceful_shutdown_filter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b912ea88e4ba4741b7d7fe36b8bbd3ba158abe63
--- /dev/null
+++ b/filter/impl/graceful_shutdown_filter.go
@@ -0,0 +1,87 @@
+/*
+ * 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 impl
+
+import (
+	"sync/atomic"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/filter"
+	"github.com/apache/dubbo-go/filter/common"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+func init() {
+	var consumerFiler = &gracefulShutdownFilter{
+		shutdownConfig: config.GetConsumerConfig().ShutdownConfig,
+	}
+	var providerFilter = &gracefulShutdownFilter{
+		shutdownConfig: config.GetProviderConfig().ShutdownConfig,
+	}
+
+	extension.SetFilter(constant.CONSUMER_SHUTDOWN_FILTER, func() filter.Filter {
+		return consumerFiler
+	})
+
+	extension.SetFilter(constant.PROVIDER_SHUTDOWN_FILTER, func() filter.Filter {
+		return providerFilter
+	})
+}
+
+type gracefulShutdownFilter struct {
+	activeCount    int32
+	shutdownConfig *config.ShutdownConfig
+}
+
+func (gf *gracefulShutdownFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+	if gf.rejectNewRequest() {
+		logger.Info("The application is closing, new request will be rejected.")
+		return gf.getRejectHandler().RejectedExecution(invoker.GetUrl(), invocation)
+	}
+	atomic.AddInt32(&gf.activeCount, 1)
+	return invoker.Invoke(invocation)
+}
+
+func (gf *gracefulShutdownFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+	atomic.AddInt32(&gf.activeCount, -1)
+	// although this isn't thread safe, it won't be a problem if the gf.rejectNewRequest() is true.
+	if gf.shutdownConfig != nil && gf.activeCount <= 0 {
+		gf.shutdownConfig.RequestsFinished = true
+	}
+	return result
+}
+
+func (gf *gracefulShutdownFilter) rejectNewRequest() bool {
+	if gf.shutdownConfig == nil {
+		return false
+	}
+	return gf.shutdownConfig.RejectRequest
+}
+
+func (gf *gracefulShutdownFilter) getRejectHandler() common.RejectedExecutionHandler {
+	handler := constant.DEFAULT_KEY
+	if gf.shutdownConfig != nil && len(gf.shutdownConfig.RejectRequestHandler) > 0 {
+		handler = gf.shutdownConfig.RejectRequestHandler
+	}
+	return extension.GetRejectedExecutionHandler(handler)
+}
diff --git a/filter/impl/graceful_shutdown_filter_test.go b/filter/impl/graceful_shutdown_filter_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..21da167ea0f201ea357c51cab0ecb4f8ebec0957
--- /dev/null
+++ b/filter/impl/graceful_shutdown_filter_test.go
@@ -0,0 +1,76 @@
+/*
+ * 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 impl
+
+import (
+	"net/url"
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/config"
+	filterCommon "github.com/apache/dubbo-go/filter/common"
+	"github.com/apache/dubbo-go/filter/common/impl"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+)
+
+func TestGenericFilter_Invoke(t *testing.T) {
+	invoc := invocation.NewRPCInvocation("GetUser", []interface{}{"OK"}, make(map[string]string, 0))
+
+	invokeUrl := common.NewURLWithOptions(
+		common.WithParams(url.Values{}))
+
+	shutdownFilter := extension.GetFilter(constant.PROVIDER_SHUTDOWN_FILTER).(*gracefulShutdownFilter)
+
+	providerConfig := config.GetProviderConfig()
+
+	assert.False(t, shutdownFilter.rejectNewRequest())
+	assert.Nil(t, providerConfig.ShutdownConfig)
+
+	assert.Equal(t, extension.GetRejectedExecutionHandler(constant.DEFAULT_KEY),
+		shutdownFilter.getRejectHandler())
+
+	result := shutdownFilter.Invoke(protocol.NewBaseInvoker(*invokeUrl), invoc)
+	assert.NotNil(t, result)
+	assert.Nil(t, result.Error())
+
+	providerConfig.ShutdownConfig = &config.ShutdownConfig{
+		RejectRequest:        true,
+		RejectRequestHandler: "mock",
+	}
+	shutdownFilter.shutdownConfig = providerConfig.ShutdownConfig
+
+	assert.True(t, shutdownFilter.rejectNewRequest())
+	result = shutdownFilter.OnResponse(nil, protocol.NewBaseInvoker(*invokeUrl), invoc)
+
+	rejectHandler := &impl.OnlyLogRejectedExecutionHandler{}
+	extension.SetRejectedExecutionHandler("mock", func() filterCommon.RejectedExecutionHandler {
+		return rejectHandler
+	})
+	assert.True(t, providerConfig.ShutdownConfig.RequestsFinished)
+	assert.Equal(t, rejectHandler, shutdownFilter.getRejectHandler())
+
+}
diff --git a/go.sum b/go.sum
index ee7072bd1dfecf798071264d1c49072a97220ca4..9855250a90f72eca314bf54cd9bea03a619b6a5e 100644
--- a/go.sum
+++ b/go.sum
@@ -37,8 +37,6 @@ github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod
 github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
 github.com/apache/dubbo-go-hessian2 v1.2.5-0.20191029001541-894e45c9aaaa h1:11TO1wiM5bvGAVrmfN5atD8gZqUSPE1TBoIs8sI6Abk=
 github.com/apache/dubbo-go-hessian2 v1.2.5-0.20191029001541-894e45c9aaaa/go.mod h1:LWnndnrFXZmJLAzoyNAPNHSIJ1KOHVkTSsHgC3YYWlo=
-github.com/apache/dubbo-go-hessian2 v1.3.0 h1:ZhQYDm8GHqIp6i53T4ZJHQBN11nAYAjxlwoVznfyvD8=
-github.com/apache/dubbo-go-hessian2 v1.3.0/go.mod h1:LWnndnrFXZmJLAzoyNAPNHSIJ1KOHVkTSsHgC3YYWlo=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
@@ -104,8 +102,6 @@ github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF
 github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
 github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/dubbogo/getty v1.3.0 h1:GImOCANdts7dlRqi9GMVsZJnfst9EPyjTVTR1AesOD8=
-github.com/dubbogo/getty v1.3.0/go.mod h1:K4b3MkGLf7T+lMgQNFgpg0dI1Wvv1PTisFs1Psf86kU=
 github.com/dubbogo/getty v1.3.1 h1:9fehwTo/D6+z6/+kADMbhbKeMkP80o/3g+XwV5lFLTY=
 github.com/dubbogo/getty v1.3.1/go.mod h1:dtLOEb1v6EMHsQNYRWEACiRLmTWB2kJGUAj1aXayPOg=
 github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI=
diff --git a/protocol/mock/mock_invoker.go b/protocol/mock/mock_invoker.go
index 557dafa277e95c39d0b960436ac10ba8842c9186..c509cef054f5a23fe504486e01d7cc0e8772711d 100644
--- a/protocol/mock/mock_invoker.go
+++ b/protocol/mock/mock_invoker.go
@@ -1,3 +1,19 @@
+//  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.
+//
+
 // Code generated by MockGen. DO NOT EDIT.
 // Source: invoker.go
 
diff --git a/registry/etcdv3/listener.go b/registry/etcdv3/listener.go
index e0dc09908567ffcd8b8f77a9627c83876906e792..31d62fa916e5659cf424839cedf8f063fabedaa0 100644
--- a/registry/etcdv3/listener.go
+++ b/registry/etcdv3/listener.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/registry/etcdv3/listener_test.go b/registry/etcdv3/listener_test.go
index 00024d28949f8b517d49f45ce6f16422d67b0a6b..c064f99c6c4b447a6c81093b87d99e1d1ba6d17a 100644
--- a/registry/etcdv3/listener_test.go
+++ b/registry/etcdv3/listener_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go
index 4ee90969e57fc50344c914f5332134e6f7f01b89..b058113c69b8007803a8a18c1b5e0c3af8c184f4 100644
--- a/registry/etcdv3/registry.go
+++ b/registry/etcdv3/registry.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/registry/etcdv3/registry_test.go b/registry/etcdv3/registry_test.go
index 6da9ad9d7d13bb0b6f8d1dab9b582669735ceec8..3f8c0f4cfccc2bcc68fc1e55fa69d74e9f0f8c0f 100644
--- a/registry/etcdv3/registry_test.go
+++ b/registry/etcdv3/registry_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/registry/nacos/listener.go b/registry/nacos/listener.go
index 1f264ec9e4ba9b8e970eba7da3b46d8792831dea..25cd3d09b5711e4e7db56cd8e40f3283f3252e10 100644
--- a/registry/nacos/listener.go
+++ b/registry/nacos/listener.go
@@ -1,3 +1,20 @@
+/*
+ * 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 (
diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go
index 810a1cb05fec780868cf7767a9fcf8a7ccbd2b41..a8b9fa83fa73858064e570722341c14f974f5c9e 100644
--- a/registry/nacos/registry.go
+++ b/registry/nacos/registry.go
@@ -1,3 +1,20 @@
+/*
+ * 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 (
diff --git a/registry/nacos/registry_test.go b/registry/nacos/registry_test.go
index 023ff788091c0c0f7c83ab213d8ab52006cfdc81..e6ab693cd3f5432fe30c2b83011cd56e44ac509f 100644
--- a/registry/nacos/registry_test.go
+++ b/registry/nacos/registry_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 (
diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go
index c25028d58f32f4028779fd6c050e60eef2bd7bd5..5a4cc2c66e506360c02b9289f0606692ac168a23 100644
--- a/registry/zookeeper/listener.go
+++ b/registry/zookeeper/listener.go
@@ -92,7 +92,7 @@ func (l *RegistryConfigurationListener) Next() (*registry.ServiceEvent, error) {
 			return nil, perrors.New("listener stopped")
 
 		case <-l.registry.done:
-			logger.Warnf("zk consumer register has quit, so zk event listener exit asap now.")
+			logger.Warnf("zk consumer register has quit, so zk event listener exit now.")
 			return nil, perrors.New("listener stopped")
 
 		case e := <-l.events:
diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go
index 57d1211fe30e00dcb1ad16733f36b7969ebaf505..050968565387fd31871b0aa8e9969496d39f6534 100644
--- a/remoting/etcdv3/client.go
+++ b/remoting/etcdv3/client.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/remoting/etcdv3/client_test.go b/remoting/etcdv3/client_test.go
index 187789e0abfac6a0e195bebd68ce4b91e0f9bdec..8f9b80cd30a9791709a0b2e83b9e59e0046f4c6c 100644
--- a/remoting/etcdv3/client_test.go
+++ b/remoting/etcdv3/client_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/remoting/etcdv3/facade.go b/remoting/etcdv3/facade.go
index e75b39d6bcd7f67f7606c6b212f59e7a42178fd8..499044b8d77d3dcd8d32b0cb70cb78f84fae8ec4 100644
--- a/remoting/etcdv3/facade.go
+++ b/remoting/etcdv3/facade.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/remoting/etcdv3/listener.go b/remoting/etcdv3/listener.go
index f5401917e208f41d3ea84e47c46f535b344e2784..a4d5805a6dbf3c76f43cb6085653c791b33ab119 100644
--- a/remoting/etcdv3/listener.go
+++ b/remoting/etcdv3/listener.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (
diff --git a/remoting/etcdv3/listener_test.go b/remoting/etcdv3/listener_test.go
index 33904a21345ec0ac7ee1adbb239a0a7a44852387..7da85819730eaeb1c6931b0e13de26e2e171bec2 100644
--- a/remoting/etcdv3/listener_test.go
+++ b/remoting/etcdv3/listener_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 etcdv3
 
 import (