diff --git a/README.md b/README.md
index 6ff358d9d603cb25833a36afb774cc46595e63f5..72f59413200d289fac865d328468a9712b0a7f2f 100644
--- a/README.md
+++ b/README.md
@@ -27,29 +27,66 @@ If you wanna know more about dubbo-go, please visit this reference [Project Arch
 
 Finished List:
 
-- Role: Consumer, Provider
-- Transport: HTTP, TCP
-- Codec: JsonRPC v2, Hessian v2
-- Registry: ZooKeeper/[etcd v3](https://github.com/apache/dubbo-go/pull/148)/[nacos](https://github.com/apache/dubbo-go/pull/151)/[consul](https://github.com/apache/dubbo-go/pull/121)
-- Dynamic Configure Center & Service Management Configurator: Zookeeper
-- Cluster Strategy: Failover/[Failfast](https://github.com/apache/dubbo-go/pull/140)/[Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)/[Available](https://github.com/apache/dubbo-go/pull/155)/[Broadcast](https://github.com/apache/dubbo-go/pull/158)/[Forking](https://github.com/apache/dubbo-go/pull/161)
-- Load Balance: Random/[RoundRobin](https://github.com/apache/dubbo-go/pull/66)/[LeastActive](https://github.com/apache/dubbo-go/pull/65)
-- Filter: Echo Health Check/[Circuit break and service downgrade](https://github.com/apache/dubbo-go/pull/133)/[TokenFilter](https://github.com/apache/dubbo-go/pull/202)/[AccessLogFilter](https://github.com/apache/dubbo-go/pull/214)/[TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237)/[ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246)
-- Other feature: [generic invoke](https://github.com/apache/dubbo-go/pull/122)/start check/connecting certain provider/multi-protocols/multi-registries/multi-versions/service group
+- Role
+    * Consumer
+    * Provider
+
+- Transport
+    * HTTP
+    * TCP
+
+- Codec
+    * JsonRPC V2
+    * Hessian V2
+    
+- Registry
+    * ZooKeeper
+    * [etcd v3](https://github.com/apache/dubbo-go/pull/148)
+    * [nacos](https://github.com/apache/dubbo-go/pull/151)
+    * [consul](https://github.com/apache/dubbo-go/pull/121)
+    
+- Dynamic Configure Center & Service Management Configurator
+    * Zookeeper
+    * [apollo](https://github.com/apache/dubbo-go/pull/250)
+
+- Cluster Strategy
+    * Failover
+    * [Failfast](https://github.com/apache/dubbo-go/pull/140)
+    * [Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)
+    * [Available](https://github.com/apache/dubbo-go/pull/155)
+    * [Broadcast](https://github.com/apache/dubbo-go/pull/158)
+    * [Forking](https://github.com/apache/dubbo-go/pull/161)
+    
+- Load Balance
+    * Random
+    * [RoundRobin](https://github.com/apache/dubbo-go/pull/66)
+    * [LeastActive](https://github.com/apache/dubbo-go/pull/65)
+    
+- Filter
+    * Echo Health Check
+    * [Circuit break and service downgrade](https://github.com/apache/dubbo-go/pull/133)
+    * [TokenFilter](https://github.com/apache/dubbo-go/pull/202)
+    * [AccessLogFilter](https://github.com/apache/dubbo-go/pull/214)
+    * [TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237)
+    * [ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246)
+    
+- Invoke
+    * [generic invoke](https://github.com/apache/dubbo-go/pull/122)
+    
+- Others:
+    * start check
+    * connecting certain provider
+    * multi-protocols
+    * multi-registries
+    * multi-versions
+    * service group
 
 Working List:
 
 - Load Balance: ConsistentHash
 - Registry: k8s
-- Configure Center: apollo
 - Metadata Center (dubbo v2.7.x)
-- Metrics: Promethus(dubbo v2.7.x)
-
-Todo List:
-
-- Registry: kubernetes
-- Routing: istio
-- tracing (dubbo ecosystem)
+- Metrics: Opentracing/Promethus(dubbo v2.7.x)
 
 You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap).
 
diff --git a/README_CN.md b/README_CN.md
index 7a7b061960e8dcc49f1da0ba6490ca8bbbf09e22..86eeb8dbe2ae8c8209c7135402aaaf626e06b9cf 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -26,32 +26,68 @@ Apache License, Version 2.0
 
 瀹炵幇鍒楄〃:
 
-- 瑙掕壊绔�: Consumer, Provider
-- 浼犺緭鍗忚: HTTP, TCP
-- 搴忓垪鍖栧崗璁�: JsonRPC v2, Hessian v2
-- 娉ㄥ唽涓績: ZooKeeper/[etcd v3](https://github.com/apache/dubbo-go/pull/148)/[nacos](https://github.com/apache/dubbo-go/pull/151)/[consul](https://github.com/apache/dubbo-go/pull/121)
-- 鍔ㄦ€侀厤缃腑蹇冧笌鏈嶅姟娌荤悊閰嶇疆鍣紙config center锛�: Zookeeper
-- 闆嗙兢绛栫暐: Failover/[Failfast](https://github.com/apache/dubbo-go/pull/140)/[Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)/[Available](https://github.com/apache/dubbo-go/pull/155)/[Broadcast](https://github.com/apache/dubbo-go/pull/158)/[Forking](https://github.com/apache/dubbo-go/pull/161)
-- 璐熻浇鍧囪 绛栫暐: Random/[RoundRobin](https://github.com/apache/dubbo-go/pull/66)/[LeastActive](https://github.com/apache/dubbo-go/pull/65)
-- 杩囨护鍣�: Echo Health Check/[鏈嶅姟鐔旀柇&闄嶇骇](https://github.com/apache/dubbo-go/pull/133)/[TokenFilter](https://github.com/apache/dubbo-go/pull/202)/[AccessLogFilter](https://github.com/apache/dubbo-go/pull/214)/[TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237)[ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246)
-- 鍏朵粬鍔熻兘鏀寔: [娉涘寲璋冪敤](https://github.com/apache/dubbo-go/pull/122)/鍚姩鏃舵鏌�/鏈嶅姟鐩磋繛/澶氭湇鍔″崗璁�/澶氭敞鍐屼腑蹇�/澶氭湇鍔$増鏈�/鏈嶅姟鍒嗙粍
+- 瑙掕壊绔�
+    * Consumer
+    * Provider
+    
+- 浼犺緭鍗忚
+    * HTTP
+    * TCP
+
+- 搴忓垪鍖栧崗璁�
+    * JsonRPC V2
+    * Hessian V2
+    
+- 娉ㄥ唽涓績
+    * ZooKeeper
+    * [etcd v3](https://github.com/apache/dubbo-go/pull/148)
+    * [nacos](https://github.com/apache/dubbo-go/pull/151)
+    * [consul](https://github.com/apache/dubbo-go/pull/121)
+    
+- 鍔ㄦ€侀厤缃腑蹇冧笌鏈嶅姟娌荤悊閰嶇疆鍣�
+    * Zookeeper
+    * [apollo](https://github.com/apache/dubbo-go/pull/250)
+    
+- 闆嗙兢绛栫暐
+    * Failover
+    * [Failfast](https://github.com/apache/dubbo-go/pull/140)
+    * [Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)
+    * [Available](https://github.com/apache/dubbo-go/pull/155)
+    * [Broadcast](https://github.com/apache/dubbo-go/pull/158)
+    * [Forking](https://github.com/apache/dubbo-go/pull/161)
+   
+- 璐熻浇鍧囪 绛栫暐
+    * Random
+    * [RoundRobin](https://github.com/apache/dubbo-go/pull/66)
+    * [LeastActive](https://github.com/apache/dubbo-go/pull/65)
+    
+- 杩囨护鍣�
+    * Echo Health Check
+    * [鏈嶅姟鐔旀柇&闄嶇骇](https://github.com/apache/dubbo-go/pull/133)
+    * [TokenFilter](https://github.com/apache/dubbo-go/pull/202)
+    * [AccessLogFilter](https://github.com/apache/dubbo-go/pull/214)
+    * [TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237)
+    * [ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246)
+    
+- 璋冪敤
+    * [娉涘寲璋冪敤](https://github.com/apache/dubbo-go/pull/122)
+    
+- 鍏朵粬鍔熻兘鏀寔:
+    * 鍚姩鏃舵鏌�
+    * 鏈嶅姟鐩磋繛
+    * 澶氭湇鍔″崗璁�
+    * 澶氭敞鍐屼腑蹇�
+    * 澶氭湇鍔$増鏈�
+    * 鏈嶅姟鍒嗙粍
 
 寮€鍙戜腑鍒楄〃:
 
-- 闆嗙兢绛栫暐: Forking
 - 璐熻浇鍧囪 绛栫暐: ConsistentHash
 - 娉ㄥ唽涓績: k8s
-- 閰嶇疆涓績: apollo
 - 鍏冩暟鎹腑蹇� (dubbo v2.7.x)
-- Metrics: Promethus(dubbo v2.7.x)
+- Metrics: Opentracing/Promethus(dubbo v2.7.x)
 
-浠诲姟鍒楄〃:
-
-- 娉ㄥ唽涓績: kubernetes
-- Routing: istio
-- tracing (dubbo ecosystem)
-
-浣犲彲浠ラ€氳繃璁块棶 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 鐭ラ亾鏇村鍏充簬 dubbo-go 鐨勪俊鎭�
+浣犲彲浠ラ€氳繃璁块棶 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 鐭ラ亾鏇村鍏充簬 dubbo-go 鐨勪俊鎭€�
 
 ## 鏂囨。
 
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 a52f15875a31a99f4d6a305454fce92aa3f29cdc..17368b45ae49d06310ecff4b9cf05e7b8b4d26f7 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 (
@@ -116,6 +118,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..fedb2c15ecdab62d17f0a4e83c45522f1c18acb0
--- /dev/null
+++ b/config/graceful_shutdown.go
@@ -0,0 +1,229 @@
+/*
+ * 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"
+	"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.
+ * The signals are different on different platforms.
+ * We define them by using 'package build' feature https://golang.org/pkg/go/build/
+ */
+
+func GracefulShutdownInit() {
+
+	signals := make(chan os.Signal, 1)
+
+	signal.Notify(signals, ShutdownSignals...)
+
+	go func() {
+		select {
+		case sig := <-signals:
+			logger.Infof("get signal %s, application will shutdown.", sig)
+			// gracefulShutdownOnce.Do(func() {
+			BeforeShutdown()
+
+			// those signals' original behavior is exit with dump ths stack, so we try to keep the behavior
+			for _, dumpSignal := range DumpHeapShutdownSignals {
+				if sig == dumpSignal {
+					debug.WriteHeapDump(os.Stdout.Fd())
+				}
+			}
+
+			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_signal_darwin.go b/config/graceful_shutdown_signal_darwin.go
new file mode 100644
index 0000000000000000000000000000000000000000..59c1a5d149c2e9db8e9ac981adec107cafc863ad
--- /dev/null
+++ b/config/graceful_shutdown_signal_darwin.go
@@ -0,0 +1,30 @@
+/*
+ * 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"
+	"syscall"
+)
+
+var ShutdownSignals = []os.Signal{os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP,
+	syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP,
+	syscall.SIGABRT, syscall.SIGSYS}
+
+var DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL,
+	syscall.SIGTRAP, syscall.SIGABRT, syscall.SIGSYS}
diff --git a/config/graceful_shutdown_signal_linux.go b/config/graceful_shutdown_signal_linux.go
new file mode 100644
index 0000000000000000000000000000000000000000..59c1a5d149c2e9db8e9ac981adec107cafc863ad
--- /dev/null
+++ b/config/graceful_shutdown_signal_linux.go
@@ -0,0 +1,30 @@
+/*
+ * 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"
+	"syscall"
+)
+
+var ShutdownSignals = []os.Signal{os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP,
+	syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP,
+	syscall.SIGABRT, syscall.SIGSYS}
+
+var DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL,
+	syscall.SIGTRAP, syscall.SIGABRT, syscall.SIGSYS}
diff --git a/config/graceful_shutdown_signal_windows.go b/config/graceful_shutdown_signal_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..91b2bce7c2311ecbe9a1255be3e7b7b357a9b403
--- /dev/null
+++ b/config/graceful_shutdown_signal_windows.go
@@ -0,0 +1,29 @@
+/*
+ * 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"
+	"syscall"
+)
+
+var ShutdownSignals = []os.Signal{os.Interrupt, os.Kill, syscall.SIGKILL,
+	syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP,
+	syscall.SIGABRT}
+
+var DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT}
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/reference_config.go b/config/reference_config.go
index c63ac2ef28ff85d07b76ad0f5fef669d83bca3a5..8703c459bab306f98beb1668a1f9438126586f24 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -183,7 +183,7 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	//filter
 	var defaultReferenceFilter = constant.DEFAULT_REFERENCE_FILTERS
 	if refconfig.Generic {
-		defaultReferenceFilter = constant.GENERIC_REFERENCE_FILTERS + defaultReferenceFilter
+		defaultReferenceFilter = constant.GENERIC_REFERENCE_FILTERS + "," + defaultReferenceFilter
 	}
 	urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, defaultReferenceFilter))
 
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/jsonrpc/http.go b/protocol/jsonrpc/http.go
index b64a3a344e95164b8f49556cdc155bf34642a83b..3d99786624c71818cc5f787c8695d1c116c35707 100644
--- a/protocol/jsonrpc/http.go
+++ b/protocol/jsonrpc/http.go
@@ -66,8 +66,8 @@ type HTTPOptions struct {
 }
 
 var defaultHTTPOptions = HTTPOptions{
-	HandshakeTimeout: 3e9,
-	HTTPTimeout:      3e9,
+	HandshakeTimeout: 3 * time.Second,
+	HTTPTimeout:      3 * time.Second,
 }
 
 type HTTPClient struct {
@@ -115,7 +115,7 @@ func (c *HTTPClient) Call(ctx context.Context, service common.URL, req *Request,
 
 	reqTimeout := c.options.HTTPTimeout
 	if reqTimeout <= 0 {
-		reqTimeout = 1e8
+		reqTimeout = 100 * time.Millisecond
 	}
 	httpHeader.Set("Timeout", reqTimeout.String())
 	if md, ok := ctx.Value(constant.DUBBOGO_CTX_KEY).(map[string]string); ok {
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/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..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:
@@ -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 {
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 (