diff --git a/.gitignore b/.gitignore
index 0b3673bf316a409b5caadf09f3fa58d42ad8f968..3769d10aa12348464cb315fd336bf6b7234069cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@
 
 # Output of the go coverage tool, specifically when used with LiteIDE
 *.out
+coverage.txt
 
 *.idea
 *.iml
@@ -22,3 +23,4 @@ vendor/
 
 logs/
 .vscode/
+coverage.txt
diff --git a/.travis.yml b/.travis.yml
index 2038d8ecc81ce319906b66333458eb6eda9afc30..ea6b2035584ba07ae7caa709f83be59cf20c730e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
 language: go
 
 go:
-  - "1.11"
   - "1.12"
 
 env:
@@ -11,6 +10,10 @@ install: true
 
 script:
   - go fmt ./... && [[ -z `git status -s` ]]
+  - 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/
+  - cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar registry/zookeeper/zookeeper-4unittest/contrib/fatjar/
   - go mod vendor && go test ./... -coverprofile=coverage.txt -covermode=atomic
 
 after_success:
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000000000000000000000000000000000000..a9bd809c5c43a9d88a773b5f0c421b252abf38de
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,5 @@
+Apache Dubbo Go
+Copyright 2018-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index 245b693fb3dac5c7d6058a2d57dcc33c1d41e309..ccc6ae52edf5f5086213feb3d3d0823ed46e0b96 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,10 @@
 ---
 Apache Dubbo Go Implementation.
 
+![Apache Dubbo-go](./dubbogo.png "Apache Dubbo-go")
+
+Apache/Dubbo-go image, licensed under [Creative Commons 3.0 Attributions license](https://creativecommons.org/licenses/by/3.0/).
+
 ## License
 
 Apache License, Version 2.0
@@ -29,19 +33,19 @@ Finished List:
 - Role: Consumer, Provider
 - Transport: HTTP, TCP
 - Codec: JsonRPC v2, Hessian v2
-- Registry: ZooKeeper
-- Routing: Rule(dubbo v2.6.x)
+- Registry: ZooKeeper/[etcd](https://github.com/apache/dubbo-go/pull/148)/[nacos](https://github.com/apache/dubbo-go/pull/151)
 - Configure Center: Zookeeper
-- Cluster Strategy: Failover
-- Load Balance: Random, RoundRobin, LeastActive
+- Cluster Strategy: Failover/[Failfast](https://github.com/apache/dubbo-go/pull/140)/[Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)/Available/Broadcast
+- 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
+- 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
 
 Working List:
 
-- Cluster Strategy: Failfast/Failsafe/Failback/Forking
+- Cluster Strategy: Forking
 - Load Balance: ConsistentHash
-- Filter: TokenFilter/AccessLogFilter/CountFilter/ActiveLimitFilter/ExecuteLimitFilter/GenericFilter/TpsLimitFilter
-- Registry: etcd/k8s/consul/nacos
+- Filter: TokenFilter/AccessLogFilter/CountFilter/ExecuteLimitFilter/TpsLimitFilter
+- Registry: k8s/consul
 - Configure Center: apollo
 - Dynamic Configuration Center & Metadata Center (dubbo v2.7.x)
 - Metrics: Promethus(dubbo v2.7.x)
@@ -54,12 +58,23 @@ Todo List:
 
 You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap).
 
+## Document
 
+TODO
 
 ## Quick Start
 
 The subdirectory examples shows how to use dubbo-go. Please read the [examples/README.md](https://github.com/apache/dubbo-go/blob/develop/examples/README.md) carefully to learn how to dispose the configuration and compile the program.
 
+## Running unit tests
+
+```bash
+go test ./...
+
+# coverage
+go test ./... -coverprofile=coverage.txt -covermode=atomic
+```
+
 ## Contributing
 
 If you are willing to do some code contributions and document contributions to [Apache/dubbo-go](https://github.com/apache/dubbo-go), please visit [contribution intro](https://github.com/apache/dubbo-go/blob/master/cg.md).
diff --git a/README_CN.md b/README_CN.md
index a5502d1379ac4e3ba977ac1727c1c30f9ce488b2..e021be55765241be93f4c9c66cca1beb573cc1bb 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -5,6 +5,9 @@
 
 ---
 Apache Dubbo Go 语言实现
+![Apache Dubbo-go](./dubbogo.png "Apache Dubbo-go")
+
+Apache/Dubbo-go image, licensed under [Creative Commons 3.0 Attributions license](https://creativecommons.org/licenses/by/3.0/).
 
 ## 证书 ##
 
@@ -26,38 +29,51 @@ Apache License, Version 2.0
 
 实现列表:
 
-- Role: Consumer, Provider
-- Transport: HTTP, TCP
-- Codec: JsonRPC v2, Hessian v2
-- Registry: ZooKeeper
-- Routing: Rule(dubbo v2.6.x)
-- Configure Center: Zookeeper
-- Cluster Strategy: Failover
-- Load Balance: Random, RoundRobin, LeastActive
-- Filter: Echo Health Check
+- 角色端: Consumer, Provider
+- 传输协议: HTTP, TCP
+- 序列化协议: JsonRPC v2, Hessian v2
+- 注册中心: ZooKeeper/[etcd](https://github.com/apache/dubbo-go/pull/148)/[nacos](https://github.com/apache/dubbo-go/pull/151)
+- 配置中心: Zookeeper
+- 集群策略: Failover/[Failfast](https://github.com/apache/dubbo-go/pull/140)/[Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)/Available/Broadcast
+- 负载均衡策略: 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/122)/启动时检查/服务直连/多服务协议/多注册中心/多服务版本/服务分组
 
 开发中列表:
 
-- Cluster Strategy: Failfast/Failsafe/Failback/Forking
-- Load Balance: ConsistentHash
-- Filter: TokenFilter/AccessLogFilter/CountFilter/ActiveLimitFilter/ExecuteLimitFilter/GenericFilter/TpsLimitFilter
-- Registry: etcd/k8s/consul/nacos
-- Configure Center: apollo
-- Dynamic Configuration Center & Metadata Center (dubbo v2.7.x)
+- 集群策略: Forking
+- 负载均衡策略: ConsistentHash
+- 过滤器: TokenFilter/AccessLogFilter/CountFilter/ExecuteLimitFilter/TpsLimitFilter
+- 注册中心: etcd/k8s/consul/nacos
+- 配置中心: apollo
+- 动态配置中心 & 元数据中心 (dubbo v2.7.x)
 - Metrics: Promethus(dubbo v2.7.x)
 
 任务列表:
 
-- Registry: kubernetes
+- 注册中心: kubernetes
 - Routing: istio
 - tracing (dubbo ecosystem)
 
 你可以通过访问 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 知道更多关于 dubbo-go 的信息
 
+## 文档
+
+TODO
+
 ## 快速开始 ##
 
 这个子目录下的例子展示了如何使用 dubbo-go 。请仔细阅读 [examples/README.md](https://github.com/apache/dubbo-go/blob/develop/examples/README.md) 学习如何处理配置并编译程序。
 
+## 运行单测
+
+```bash
+go test ./...
+
+# 覆盖率
+go test ./... -coverprofile=coverage.txt -covermode=atomic
+```
+
 ## 如何贡献
 
 如果您愿意给 [Apache/dubbo-go](https://github.com/apache/dubbo-go) 贡献代码或者文档,我们都热烈欢迎。具体请参考 [contribution intro](https://github.com/apache/dubbo-go/blob/master/cg.md)。
diff --git a/cluster/cluster_impl/available_cluster.go b/cluster/cluster_impl/available_cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..7e748cd938319ff437bb3fb6c7945b857d316069
--- /dev/null
+++ b/cluster/cluster_impl/available_cluster.go
@@ -0,0 +1,40 @@
+/*
+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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type availableCluster struct{}
+
+const available = "available"
+
+func init() {
+	extension.SetCluster(available, NewAvailableCluster)
+}
+
+func NewAvailableCluster() cluster.Cluster {
+	return &availableCluster{}
+}
+
+func (cluser *availableCluster) Join(directory cluster.Directory) protocol.Invoker {
+	return NewAvailableClusterInvoker(directory)
+}
diff --git a/cluster/cluster_impl/available_cluster_invoker.go b/cluster/cluster_impl/available_cluster_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..c59c0702c216fe5c58d190a023322aaa00ac9c17
--- /dev/null
+++ b/cluster/cluster_impl/available_cluster_invoker.go
@@ -0,0 +1,61 @@
+/*
+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 cluster_impl
+
+import (
+	"fmt"
+)
+
+import (
+	"github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type availableClusterInvoker struct {
+	baseClusterInvoker
+}
+
+func NewAvailableClusterInvoker(directory cluster.Directory) protocol.Invoker {
+	return &availableClusterInvoker{
+		baseClusterInvoker: newBaseClusterInvoker(directory),
+	}
+}
+
+func (invoker *availableClusterInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+	invokers := invoker.directory.List(invocation)
+	err := invoker.checkInvokers(invokers, invocation)
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	err = invoker.checkWhetherDestroyed()
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	for _, ivk := range invokers {
+		if ivk.IsAvailable() {
+			return ivk.Invoke(invocation)
+		}
+	}
+	return &protocol.RPCResult{Err: errors.New(fmt.Sprintf("no provider available in %v", invokers))}
+}
diff --git a/cluster/cluster_impl/available_cluster_invoker_test.go b/cluster/cluster_impl/available_cluster_invoker_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..04032a7f24dec0e73acb15921f753921391f1515
--- /dev/null
+++ b/cluster/cluster_impl/available_cluster_invoker_test.go
@@ -0,0 +1,88 @@
+/*
+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 cluster_impl
+
+import (
+	"context"
+	"strings"
+	"testing"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster/directory"
+	"github.com/apache/dubbo-go/cluster/loadbalance"
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/protocol/mock"
+)
+
+var (
+	availableUrl, _ = common.NewURL(context.Background(), "dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")
+)
+
+func registerAvailable(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker {
+	extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance)
+	availableCluster := NewAvailableCluster()
+
+	invokers := []protocol.Invoker{}
+	invokers = append(invokers, invoker)
+	invoker.EXPECT().GetUrl().Return(availableUrl)
+
+	staticDir := directory.NewStaticDirectory(invokers)
+	clusterInvoker := availableCluster.Join(staticDir)
+	return clusterInvoker
+}
+
+func TestAvailableClusterInvokerSuccess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerAvailable(t, invoker)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	invoker.EXPECT().IsAvailable().Return(true)
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+
+	assert.Equal(t, mockResult, result)
+}
+
+func TestAvailableClusterInvokerNoAvail(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerAvailable(t, invoker)
+
+	invoker.EXPECT().IsAvailable().Return(false)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+
+	assert.NotNil(t, result.Error())
+	assert.True(t, strings.Contains(result.Error().Error(), "no provider available"))
+	assert.Nil(t, result.Result())
+}
diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go
index 6cbed7748e496afb37f9a1e93dbc40e845c62b06..52e2156885a2e6cc3c35da75a1d0db8bcfcabec0 100644
--- a/cluster/cluster_impl/base_cluster_invoker.go
+++ b/cluster/cluster_impl/base_cluster_invoker.go
@@ -25,9 +25,10 @@ import (
 import (
 	"github.com/apache/dubbo-go/cluster"
 	"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/common/utils"
 	"github.com/apache/dubbo-go/protocol"
-	"github.com/apache/dubbo-go/version"
 )
 
 type baseClusterInvoker struct {
@@ -65,7 +66,7 @@ func (invoker *baseClusterInvoker) checkInvokers(invokers []protocol.Invoker, in
 		ip, _ := utils.GetLocalIP()
 		return perrors.Errorf("Failed to invoke the method %v. No provider available for the service %v from "+
 			"registry %v on the consumer %v using the dubbo version %v .Please check if the providers have been started and registered.",
-			invocation.MethodName(), invoker.directory.GetUrl().SubURL.Key(), invoker.directory.GetUrl().String(), ip, version.Version)
+			invocation.MethodName(), invoker.directory.GetUrl().SubURL.Key(), invoker.directory.GetUrl().String(), ip, constant.Version)
 	}
 	return nil
 
@@ -76,13 +77,13 @@ func (invoker *baseClusterInvoker) checkWhetherDestroyed() error {
 	if invoker.destroyed.Load() {
 		ip, _ := utils.GetLocalIP()
 		return perrors.Errorf("Rpc cluster invoker for %v on consumer %v use dubbo version %v is now destroyed! can not invoke any more. ",
-			invoker.directory.GetUrl().Service(), ip, version.Version)
+			invoker.directory.GetUrl().Service(), ip, constant.Version)
 	}
 	return nil
 }
 
 func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker {
-	//todo:ticky connect 粘纸连接
+	//todo:sticky connect
 	if len(invokers) == 1 {
 		return invokers[0]
 	}
@@ -115,12 +116,24 @@ func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation p
 }
 
 func isInvoked(selectedInvoker protocol.Invoker, invoked []protocol.Invoker) bool {
-	if len(invoked) > 0 {
-		for _, i := range invoked {
-			if i == selectedInvoker {
-				return true
-			}
+	for _, i := range invoked {
+		if i == selectedInvoker {
+			return true
 		}
 	}
 	return false
 }
+
+func getLoadBalance(invoker protocol.Invoker, invocation protocol.Invocation) cluster.LoadBalance {
+	url := invoker.GetUrl()
+
+	methodName := invocation.MethodName()
+	//Get the service loadbalance config
+	lb := url.GetParam(constant.LOADBALANCE_KEY, constant.DEFAULT_LOADBALANCE)
+
+	//Get the service method loadbalance config if have
+	if v := url.GetMethodParam(methodName, constant.LOADBALANCE_KEY, ""); len(v) > 0 {
+		lb = v
+	}
+	return extension.GetLoadbalance(lb)
+}
diff --git a/cluster/cluster_impl/broadcast_cluster.go b/cluster/cluster_impl/broadcast_cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..50aae3cfab8d67570b50dcab4e53bbfad29d6d30
--- /dev/null
+++ b/cluster/cluster_impl/broadcast_cluster.go
@@ -0,0 +1,40 @@
+/*
+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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type broadcastCluster struct{}
+
+const broadcast = "broadcast"
+
+func init() {
+	extension.SetCluster(broadcast, NewBroadcastCluster)
+}
+
+func NewBroadcastCluster() cluster.Cluster {
+	return &broadcastCluster{}
+}
+
+func (cluster *broadcastCluster) Join(directory cluster.Directory) protocol.Invoker {
+	return newBroadcastClusterInvoker(directory)
+}
diff --git a/cluster/cluster_impl/broadcast_cluster_invoker.go b/cluster/cluster_impl/broadcast_cluster_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..238df0acfa7fb946e38bfbfd490bce7c0bb34e60
--- /dev/null
+++ b/cluster/cluster_impl/broadcast_cluster_invoker.go
@@ -0,0 +1,59 @@
+/*
+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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type broadcastClusterInvoker struct {
+	baseClusterInvoker
+}
+
+func newBroadcastClusterInvoker(directory cluster.Directory) protocol.Invoker {
+	return &broadcastClusterInvoker{
+		baseClusterInvoker: newBaseClusterInvoker(directory),
+	}
+}
+
+func (invoker *broadcastClusterInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+	invokers := invoker.directory.List(invocation)
+	err := invoker.checkInvokers(invokers, invocation)
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+	err = invoker.checkWhetherDestroyed()
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	var result protocol.Result
+	for _, ivk := range invokers {
+		result = ivk.Invoke(invocation)
+		if result.Error() != nil {
+			logger.Warnf("broadcast invoker invoke err: %v when use invoker: %v\n", result.Error(), ivk)
+			err = result.Error()
+		}
+	}
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+	return result
+}
diff --git a/cluster/cluster_impl/broadcast_cluster_invoker_test.go b/cluster/cluster_impl/broadcast_cluster_invoker_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..565684a8ae25c648ff77aef71d2ced0665202fe7
--- /dev/null
+++ b/cluster/cluster_impl/broadcast_cluster_invoker_test.go
@@ -0,0 +1,109 @@
+/*
+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 cluster_impl
+
+import (
+	"context"
+	"errors"
+	"testing"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster/directory"
+	"github.com/apache/dubbo-go/cluster/loadbalance"
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/protocol/mock"
+)
+
+var (
+	broadcastUrl, _ = common.NewURL(context.TODO(), "dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")
+)
+
+func registerBroadcast(t *testing.T, mockInvokers ...*mock.MockInvoker) protocol.Invoker {
+	extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance)
+
+	invokers := []protocol.Invoker{}
+	for i, ivk := range mockInvokers {
+		invokers = append(invokers, ivk)
+		if i == 0 {
+			ivk.EXPECT().GetUrl().Return(broadcastUrl)
+		}
+	}
+	staticDir := directory.NewStaticDirectory(invokers)
+
+	broadcastCluster := NewBroadcastCluster()
+	clusterInvoker := broadcastCluster.Join(staticDir)
+	return clusterInvoker
+}
+
+func Test_BroadcastInvokeSuccess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invokers := make([]*mock.MockInvoker, 0)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	for i := 0; i < 3; i++ {
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	}
+
+	clusterInvoker := registerBroadcast(t, invokers...)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Equal(t, mockResult, result)
+}
+
+func Test_BroadcastInvokeFailed(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invokers := make([]*mock.MockInvoker, 0)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	mockFailedResult := &protocol.RPCResult{Err: errors.New("just failed")}
+	for i := 0; i < 10; i++ {
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	}
+	{
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult)
+	}
+	for i := 0; i < 10; i++ {
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	}
+
+	clusterInvoker := registerBroadcast(t, invokers...)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Equal(t, mockFailedResult.Err, result.Error())
+}
diff --git a/cluster/cluster_impl/failback_cluster.go b/cluster/cluster_impl/failback_cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..de22c78e947d0b8124add721ab7ff42efebcdbe4
--- /dev/null
+++ b/cluster/cluster_impl/failback_cluster.go
@@ -0,0 +1,40 @@
+/*
+ * 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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type failbackCluster struct{}
+
+const failback = "failback"
+
+func init() {
+	extension.SetCluster(failback, NewFailbackCluster)
+}
+
+func NewFailbackCluster() cluster.Cluster {
+	return &failbackCluster{}
+}
+
+func (cluster *failbackCluster) Join(directory cluster.Directory) protocol.Invoker {
+	return newFailbackClusterInvoker(directory)
+}
diff --git a/cluster/cluster_impl/failback_cluster_invoker.go b/cluster/cluster_impl/failback_cluster_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..027461ccb7f32d6383d756ac986295b6300f249c
--- /dev/null
+++ b/cluster/cluster_impl/failback_cluster_invoker.go
@@ -0,0 +1,203 @@
+/*
+ * 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 cluster_impl
+
+import (
+	"sync"
+	"time"
+)
+
+import (
+	"github.com/Workiva/go-datastructures/queue"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"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/protocol"
+)
+
+/**
+ * When fails, record failure requests and schedule for retry on a regular interval.
+ * Especially useful for services of notification.
+ *
+ * <a href="http://en.wikipedia.org/wiki/Failback">Failback</a>
+ */
+type failbackClusterInvoker struct {
+	baseClusterInvoker
+
+	once          sync.Once
+	ticker        *time.Ticker
+	maxRetries    int64
+	failbackTasks int64
+	taskList      *queue.Queue
+}
+
+func newFailbackClusterInvoker(directory cluster.Directory) protocol.Invoker {
+	invoker := &failbackClusterInvoker{
+		baseClusterInvoker: newBaseClusterInvoker(directory),
+	}
+	retriesConfig := invoker.GetUrl().GetParamInt(constant.RETRIES_KEY, constant.DEFAULT_FAILBACK_TIMES)
+	if retriesConfig <= 0 {
+		retriesConfig = constant.DEFAULT_FAILBACK_TIMES
+	}
+	failbackTasksConfig := invoker.GetUrl().GetParamInt(constant.FAIL_BACK_TASKS_KEY, constant.DEFAULT_FAILBACK_TASKS)
+	if failbackTasksConfig <= 0 {
+		failbackTasksConfig = constant.DEFAULT_FAILBACK_TASKS
+	}
+	invoker.maxRetries = retriesConfig
+	invoker.failbackTasks = failbackTasksConfig
+	return invoker
+}
+
+func (invoker *failbackClusterInvoker) process() {
+	invoker.ticker = time.NewTicker(time.Second * 1)
+	for range invoker.ticker.C {
+		// check each timeout task and re-run
+		for {
+			value, err := invoker.taskList.Peek()
+			if err == queue.ErrDisposed {
+				return
+			}
+			if err == queue.ErrEmptyQueue {
+				break
+			}
+
+			retryTask := value.(*retryTimerTask)
+			if time.Since(retryTask.lastT).Seconds() < 5 {
+				break
+			}
+
+			// ignore return. the get must success.
+			_, err = invoker.taskList.Get(1)
+			if err != nil {
+				logger.Warnf("get task found err: %v\n", err)
+				break
+			}
+
+			go func(retryTask *retryTimerTask) {
+				invoked := make([]protocol.Invoker, 0)
+				invoked = append(invoked, retryTask.lastInvoker)
+
+				retryInvoker := invoker.doSelect(retryTask.loadbalance, retryTask.invocation, retryTask.invokers, invoked)
+				var result protocol.Result
+				result = retryInvoker.Invoke(retryTask.invocation)
+				if result.Error() != nil {
+					retryTask.lastInvoker = retryInvoker
+					invoker.checkRetry(retryTask, result.Error())
+				}
+			}(retryTask)
+
+		}
+	}
+}
+
+func (invoker *failbackClusterInvoker) checkRetry(retryTask *retryTimerTask, err error) {
+	logger.Errorf("Failed retry to invoke the method %v in the service %v, wait again. The exception: %v.\n",
+		retryTask.invocation.MethodName(), invoker.GetUrl().Service(), err.Error())
+	retryTask.retries++
+	retryTask.lastT = time.Now()
+	if retryTask.retries > invoker.maxRetries {
+		logger.Errorf("Failed retry times exceed threshold (%v), We have to abandon, invocation-> %v.\n",
+			retryTask.retries, retryTask.invocation)
+	} else {
+		invoker.taskList.Put(retryTask)
+	}
+}
+
+func (invoker *failbackClusterInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+	invokers := invoker.directory.List(invocation)
+	err := invoker.checkInvokers(invokers, invocation)
+	if err != nil {
+		logger.Errorf("Failed to invoke the method %v in the service %v, wait for retry in background. Ignored exception: %v.\n",
+			invocation.MethodName(), invoker.GetUrl().Service(), err)
+		return &protocol.RPCResult{}
+	}
+	url := invokers[0].GetUrl()
+	methodName := invocation.MethodName()
+	//Get the service loadbalance config
+	lb := url.GetParam(constant.LOADBALANCE_KEY, constant.DEFAULT_LOADBALANCE)
+
+	//Get the service method loadbalance config if have
+	if v := url.GetMethodParam(methodName, constant.LOADBALANCE_KEY, ""); v != "" {
+		lb = v
+	}
+	loadbalance := extension.GetLoadbalance(lb)
+
+	invoked := make([]protocol.Invoker, 0, len(invokers))
+	var result protocol.Result
+
+	ivk := invoker.doSelect(loadbalance, invocation, invokers, invoked)
+	//DO INVOKE
+	result = ivk.Invoke(invocation)
+	if result.Error() != nil {
+		invoker.once.Do(func() {
+			invoker.taskList = queue.New(invoker.failbackTasks)
+			go invoker.process()
+		})
+
+		taskLen := invoker.taskList.Len()
+		if taskLen >= invoker.failbackTasks {
+			logger.Warnf("tasklist is too full > %d.\n", taskLen)
+			return &protocol.RPCResult{}
+		}
+
+		timerTask := newRetryTimerTask(loadbalance, invocation, invokers, ivk)
+		invoker.taskList.Put(timerTask)
+
+		logger.Errorf("Failback to invoke the method %v in the service %v, wait for retry in background. Ignored exception: %v.\n",
+			methodName, url.Service(), result.Error().Error())
+		// ignore
+		return &protocol.RPCResult{}
+	}
+
+	return result
+}
+
+func (invoker *failbackClusterInvoker) Destroy() {
+	invoker.baseClusterInvoker.Destroy()
+
+	// stop ticker
+	if invoker.ticker != nil {
+		invoker.ticker.Stop()
+	}
+
+	_ = invoker.taskList.Dispose()
+}
+
+type retryTimerTask struct {
+	loadbalance cluster.LoadBalance
+	invocation  protocol.Invocation
+	invokers    []protocol.Invoker
+	lastInvoker protocol.Invoker
+	retries     int64
+	lastT       time.Time
+}
+
+func newRetryTimerTask(loadbalance cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker,
+	lastInvoker protocol.Invoker) *retryTimerTask {
+	return &retryTimerTask{
+		loadbalance: loadbalance,
+		invocation:  invocation,
+		invokers:    invokers,
+		lastInvoker: lastInvoker,
+		lastT:       time.Now(),
+	}
+}
diff --git a/cluster/cluster_impl/failback_cluster_test.go b/cluster/cluster_impl/failback_cluster_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c94347a1251a69a10c0a4d50007ef569bd6dd996
--- /dev/null
+++ b/cluster/cluster_impl/failback_cluster_test.go
@@ -0,0 +1,242 @@
+/*
+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 cluster_impl
+
+import (
+	"context"
+	"sync"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+	perrors "github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster/directory"
+	"github.com/apache/dubbo-go/cluster/loadbalance"
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/protocol/mock"
+)
+
+var (
+	failbackUrl, _ = common.NewURL(context.TODO(), "dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")
+)
+
+// registerFailback register failbackCluster to cluster extension.
+func registerFailback(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker {
+	extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance)
+	failbackCluster := NewFailbackCluster()
+
+	invokers := []protocol.Invoker{}
+	invokers = append(invokers, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl)
+
+	staticDir := directory.NewStaticDirectory(invokers)
+	clusterInvoker := failbackCluster.Join(staticDir)
+	return clusterInvoker
+}
+
+// success firstly, failback should return origin invoke result.
+func Test_FailbackSuceess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker)
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl).Times(1)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Equal(t, mockResult, result)
+}
+
+// failed firstly, success later after one retry.
+func Test_FailbackRetryOneSuccess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker)
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes()
+
+	// failed at first
+	mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")}
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult)
+
+	// success second
+	var wg sync.WaitGroup
+	wg.Add(1)
+	now := time.Now()
+	mockSuccResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(invocation protocol.Invocation) protocol.Result {
+		delta := time.Since(now).Nanoseconds() / int64(time.Second)
+		assert.True(t, delta >= 5)
+		wg.Done()
+		return mockSuccResult
+	})
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Nil(t, result.Error())
+	assert.Nil(t, result.Result())
+	assert.Equal(t, 0, len(result.Attachments()))
+
+	// ensure the retry task has been executed
+	assert.Equal(t, int64(1), clusterInvoker.taskList.Len())
+	// wait until the retry task is executed, the taskList will be empty.
+	wg.Wait()
+	assert.Equal(t, int64(0), clusterInvoker.taskList.Len())
+
+	invoker.EXPECT().Destroy().Return()
+	clusterInvoker.Destroy()
+
+	assert.Equal(t, int64(0), clusterInvoker.taskList.Len())
+}
+
+// failed firstly, and failed again after ech retry time.
+func Test_FailbackRetryFailed(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker)
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes()
+
+	mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")}
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult)
+
+	//
+	var wg sync.WaitGroup
+	retries := 2
+	wg.Add(retries)
+	now := time.Now()
+
+	// add retry call that eventually failed.
+	for i := 0; i < retries; i++ {
+		j := i + 1
+		invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(invocation protocol.Invocation) protocol.Result {
+			delta := time.Since(now).Nanoseconds() / int64(time.Second)
+			assert.True(t, delta >= int64(5*j))
+			wg.Done()
+			return mockFailedResult
+		})
+	}
+
+	// first call should failed.
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Nil(t, result.Error())
+	assert.Nil(t, result.Result())
+	assert.Equal(t, 0, len(result.Attachments()))
+
+	wg.Wait()
+	time.Sleep(time.Second)
+	assert.Equal(t, int64(1), clusterInvoker.taskList.Len())
+
+	invoker.EXPECT().Destroy().Return()
+	clusterInvoker.Destroy()
+	// after destroy, the taskList will be empty
+	assert.Equal(t, int64(0), clusterInvoker.taskList.Len())
+}
+
+// add 10 tasks but all failed firstly, and failed again with one retry.
+func Test_FailbackRetryFailed10Times(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker)
+	clusterInvoker.maxRetries = 10
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes()
+
+	// 10 task should failed firstly.
+	mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")}
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult).Times(10)
+
+	// 10 task should retry and failed.
+	var wg sync.WaitGroup
+	wg.Add(10)
+	now := time.Now()
+	invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(invocation protocol.Invocation) protocol.Result {
+		delta := time.Since(now).Nanoseconds() / int64(time.Second)
+		assert.True(t, delta >= 5)
+		wg.Done()
+		return mockFailedResult
+	}).Times(10)
+
+	for i := 0; i < 10; i++ {
+		result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+		assert.Nil(t, result.Error())
+		assert.Nil(t, result.Result())
+		assert.Equal(t, 0, len(result.Attachments()))
+	}
+
+	wg.Wait()
+	time.Sleep(time.Second) // in order to ensure checkRetry have done
+	assert.Equal(t, int64(10), clusterInvoker.taskList.Len())
+
+	invoker.EXPECT().Destroy().Return()
+	clusterInvoker.Destroy()
+
+	assert.Equal(t, int64(0), clusterInvoker.taskList.Len())
+}
+
+func Test_FailbackOutOfLimit(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker)
+	clusterInvoker.failbackTasks = 1
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes()
+
+	mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")}
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult).Times(11)
+
+	// reached limit
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Nil(t, result.Error())
+	assert.Nil(t, result.Result())
+	assert.Equal(t, 0, len(result.Attachments()))
+
+	// all will be out of limit
+	for i := 0; i < 10; i++ {
+		result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+		assert.Nil(t, result.Error())
+		assert.Nil(t, result.Result())
+		assert.Equal(t, 0, len(result.Attachments()))
+
+		assert.Equal(t, int64(1), clusterInvoker.taskList.Len())
+	}
+
+	invoker.EXPECT().Destroy().Return()
+	clusterInvoker.Destroy()
+}
diff --git a/cluster/cluster_impl/failfast_cluster.go b/cluster/cluster_impl/failfast_cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..6301d945626103226132b433dd21e8647f53a38b
--- /dev/null
+++ b/cluster/cluster_impl/failfast_cluster.go
@@ -0,0 +1,40 @@
+/*
+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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type failfastCluster struct{}
+
+const failfast = "failfast"
+
+func init() {
+	extension.SetCluster(failfast, NewFailFastCluster)
+}
+
+func NewFailFastCluster() cluster.Cluster {
+	return &failfastCluster{}
+}
+
+func (cluster *failfastCluster) Join(directory cluster.Directory) protocol.Invoker {
+	return newFailFastClusterInvoker(directory)
+}
diff --git a/cluster/cluster_impl/failfast_cluster_invoker.go b/cluster/cluster_impl/failfast_cluster_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..734ea2c6cb19bf54a338a76a10c9cfcc59d3954b
--- /dev/null
+++ b/cluster/cluster_impl/failfast_cluster_invoker.go
@@ -0,0 +1,51 @@
+/*
+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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type failfastClusterInvoker struct {
+	baseClusterInvoker
+}
+
+func newFailFastClusterInvoker(directory cluster.Directory) protocol.Invoker {
+	return &failfastClusterInvoker{
+		baseClusterInvoker: newBaseClusterInvoker(directory),
+	}
+}
+
+func (invoker *failfastClusterInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+	invokers := invoker.directory.List(invocation)
+	err := invoker.checkInvokers(invokers, invocation)
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	loadbalance := getLoadBalance(invokers[0], invocation)
+
+	err = invoker.checkWhetherDestroyed()
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	ivk := invoker.doSelect(loadbalance, invocation, invokers, nil)
+	return ivk.Invoke(invocation)
+}
diff --git a/cluster/cluster_impl/failfast_cluster_test.go b/cluster/cluster_impl/failfast_cluster_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7a19e80ccda15aa13a1c4fcf250e05a6effa7f0b
--- /dev/null
+++ b/cluster/cluster_impl/failfast_cluster_test.go
@@ -0,0 +1,97 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cluster_impl
+
+import (
+	"context"
+	"testing"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+	perrors "github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster/directory"
+	"github.com/apache/dubbo-go/cluster/loadbalance"
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/protocol/mock"
+)
+
+var (
+	failfastUrl, _ = common.NewURL(context.TODO(), "dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")
+)
+
+// registerFailfast register failfastCluster to cluster extension.
+func registerFailfast(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker {
+	extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance)
+	failfastCluster := NewFailFastCluster()
+
+	invokers := []protocol.Invoker{}
+	invokers = append(invokers, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failfastUrl)
+
+	staticDir := directory.NewStaticDirectory(invokers)
+	clusterInvoker := failfastCluster.Join(staticDir)
+	return clusterInvoker
+}
+
+func Test_FailfastInvokeSuccess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailfast(t, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failfastUrl)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+
+	assert.NoError(t, result.Error())
+	res := result.Result().(rest)
+	assert.True(t, res.success)
+	assert.Equal(t, 0, res.tried)
+}
+
+func Test_FailfastInvokeFail(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := registerFailfast(t, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failfastUrl)
+
+	mockResult := &protocol.RPCResult{Err: perrors.New("error")}
+
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+
+	assert.NotNil(t, result.Error())
+	assert.Equal(t, "error", result.Error().Error())
+	assert.Nil(t, result.Result())
+}
diff --git a/cluster/cluster_impl/failover_cluster_invoker.go b/cluster/cluster_impl/failover_cluster_invoker.go
index cd17a85e00a1d4307b3b861467051e9719345d1a..3dd8c41dfb7b7512d7c81fa6d7f8a7c35cec0dcb 100644
--- a/cluster/cluster_impl/failover_cluster_invoker.go
+++ b/cluster/cluster_impl/failover_cluster_invoker.go
@@ -24,10 +24,8 @@ import (
 import (
 	"github.com/apache/dubbo-go/cluster"
 	"github.com/apache/dubbo-go/common/constant"
-	"github.com/apache/dubbo-go/common/extension"
 	"github.com/apache/dubbo-go/common/utils"
 	"github.com/apache/dubbo-go/protocol"
-	"github.com/apache/dubbo-go/version"
 )
 
 type failoverClusterInvoker struct {
@@ -48,17 +46,11 @@ func (invoker *failoverClusterInvoker) Invoke(invocation protocol.Invocation) pr
 	if err != nil {
 		return &protocol.RPCResult{Err: err}
 	}
-	url := invokers[0].GetUrl()
 
-	methodName := invocation.MethodName()
-	//Get the service loadbalance config
-	lb := url.GetParam(constant.LOADBALANCE_KEY, constant.DEFAULT_LOADBALANCE)
+	loadbalance := getLoadBalance(invokers[0], invocation)
 
-	//Get the service method loadbalance config if have
-	if v := url.GetMethodParam(methodName, constant.LOADBALANCE_KEY, ""); v != "" {
-		lb = v
-	}
-	loadbalance := extension.GetLoadbalance(lb)
+	methodName := invocation.MethodName()
+	url := invokers[0].GetUrl()
 
 	//get reties
 	retries := url.GetParamInt(constant.RETRIES_KEY, constant.DEFAULT_RETRIES)
@@ -98,6 +90,6 @@ func (invoker *failoverClusterInvoker) Invoke(invocation protocol.Invocation) pr
 	ip, _ := utils.GetLocalIP()
 	return &protocol.RPCResult{Err: perrors.Errorf("Failed to invoke the method %v in the service %v. Tried %v times of "+
 		"the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. Last error is %v.",
-		methodName, invoker.GetUrl().Service(), retries, providers, len(providers), len(invokers), invoker.directory.GetUrl(), ip, version.Version, result.Error().Error(),
+		methodName, invoker.GetUrl().Service(), retries, providers, len(providers), len(invokers), invoker.directory.GetUrl(), ip, constant.Version, result.Error().Error(),
 	)}
 }
diff --git a/cluster/cluster_impl/failover_cluster_test.go b/cluster/cluster_impl/failover_cluster_test.go
index cc533ea098ee76488d2f76cbbe601b275274db83..dc039db8de41ab6722b20f99c5a0c5536a42a7e6 100644
--- a/cluster/cluster_impl/failover_cluster_test.go
+++ b/cluster/cluster_impl/failover_cluster_test.go
@@ -143,8 +143,7 @@ func Test_FailoverInvoke2(t *testing.T) {
 	urlParams.Set(constant.RETRIES_KEY, "2")
 	urlParams.Set("methods.test."+constant.RETRIES_KEY, "3")
 
-	ivc := &invocation.RPCInvocation{}
-	ivc.SetMethod("test")
+	ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 	result := normalInvoke(t, 3, urlParams, ivc)
 	assert.NoError(t, result.Error())
 	count = 0
diff --git a/cluster/cluster_impl/failsafe_cluster.go b/cluster/cluster_impl/failsafe_cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ff97d25eae80980a90a03e71865bb8f9a63defe
--- /dev/null
+++ b/cluster/cluster_impl/failsafe_cluster.go
@@ -0,0 +1,40 @@
+/*
+ * 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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type failsafeCluster struct{}
+
+const failsafe = "failsafe"
+
+func init() {
+	extension.SetCluster(failsafe, NewFailsafeCluster)
+}
+
+func NewFailsafeCluster() cluster.Cluster {
+	return &failsafeCluster{}
+}
+
+func (cluster *failsafeCluster) Join(directory cluster.Directory) protocol.Invoker {
+	return newFailsafeClusterInvoker(directory)
+}
diff --git a/cluster/cluster_impl/failsafe_cluster_invoker.go b/cluster/cluster_impl/failsafe_cluster_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..b95f997fef87cf466f07c4e506e41758e7998e52
--- /dev/null
+++ b/cluster/cluster_impl/failsafe_cluster_invoker.go
@@ -0,0 +1,75 @@
+/*
+ * 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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"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/protocol"
+)
+
+/**
+ * When invoke fails, log the error message and ignore this error by returning an empty Result.
+ * Usually used to write audit logs and other operations
+ *
+ * <a href="http://en.wikipedia.org/wiki/Fail-safe">Fail-safe</a>
+ *
+ */
+type failsafeClusterInvoker struct {
+	baseClusterInvoker
+}
+
+func newFailsafeClusterInvoker(directory cluster.Directory) protocol.Invoker {
+	return &failsafeClusterInvoker{
+		baseClusterInvoker: newBaseClusterInvoker(directory),
+	}
+}
+
+func (invoker *failsafeClusterInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+	invokers := invoker.directory.List(invocation)
+
+	err := invoker.checkInvokers(invokers, invocation)
+	if err != nil {
+		return &protocol.RPCResult{}
+	}
+
+	url := invokers[0].GetUrl()
+	methodName := invocation.MethodName()
+	//Get the service loadbalance config
+	lb := url.GetParam(constant.LOADBALANCE_KEY, constant.DEFAULT_LOADBALANCE)
+	//Get the service method loadbalance config if have
+	if v := url.GetMethodParam(methodName, constant.LOADBALANCE_KEY, ""); v != "" {
+		lb = v
+	}
+	loadbalance := extension.GetLoadbalance(lb)
+
+	invoked := make([]protocol.Invoker, 0)
+	var result protocol.Result
+
+	ivk := invoker.doSelect(loadbalance, invocation, invokers, invoked)
+	//DO INVOKE
+	result = ivk.Invoke(invocation)
+	if result.Error() != nil {
+		// ignore
+		logger.Errorf("Failsafe ignore exception: %v.\n", result.Error().Error())
+		return &protocol.RPCResult{}
+	}
+	return result
+}
diff --git a/cluster/cluster_impl/failsafe_cluster_test.go b/cluster/cluster_impl/failsafe_cluster_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9ee9d9fee31b0cb24d877ab3dc0e24fb552f5f11
--- /dev/null
+++ b/cluster/cluster_impl/failsafe_cluster_test.go
@@ -0,0 +1,95 @@
+/*
+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 cluster_impl
+
+import (
+	"context"
+	"testing"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+	perrors "github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster/directory"
+	"github.com/apache/dubbo-go/cluster/loadbalance"
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/protocol/mock"
+)
+
+var (
+	failsafeUrl, _ = common.NewURL(context.TODO(), "dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")
+)
+
+// register_failsafe register failsafeCluster to cluster extension.
+func register_failsafe(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker {
+	extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance)
+	failsafeCluster := NewFailsafeCluster()
+
+	invokers := []protocol.Invoker{}
+	invokers = append(invokers, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failbackUrl)
+
+	staticDir := directory.NewStaticDirectory(invokers)
+	clusterInvoker := failsafeCluster.Join(staticDir)
+	return clusterInvoker
+}
+
+func Test_FailSafeInvokeSuccess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := register_failsafe(t, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failsafeUrl)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+
+	assert.NoError(t, result.Error())
+	res := result.Result().(rest)
+	assert.True(t, res.success)
+}
+
+func Test_FailSafeInvokeFail(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invoker := mock.NewMockInvoker(ctrl)
+	clusterInvoker := register_failsafe(t, invoker)
+
+	invoker.EXPECT().GetUrl().Return(failsafeUrl)
+
+	mockResult := &protocol.RPCResult{Err: perrors.New("error")}
+
+	invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult)
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+
+	assert.NoError(t, result.Error())
+	assert.Nil(t, result.Result())
+}
diff --git a/cluster/cluster_impl/forking_cluster.go b/cluster/cluster_impl/forking_cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..0a3c2b313ff3c4e89e592af9256fc42713419914
--- /dev/null
+++ b/cluster/cluster_impl/forking_cluster.go
@@ -0,0 +1,40 @@
+/*
+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 cluster_impl
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type forkingCluster struct{}
+
+const forking = "forking"
+
+func init() {
+	extension.SetCluster(forking, NewForkingCluster)
+}
+
+func NewForkingCluster() cluster.Cluster {
+	return &forkingCluster{}
+}
+
+func (cluster *forkingCluster) Join(directory cluster.Directory) protocol.Invoker {
+	return newForkingClusterInvoker(directory)
+}
diff --git a/cluster/cluster_impl/forking_cluster_invoker.go b/cluster/cluster_impl/forking_cluster_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..d6cf2f4b89ab4f322fa758deecae90c60742ef49
--- /dev/null
+++ b/cluster/cluster_impl/forking_cluster_invoker.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 cluster_impl
+
+import (
+	"errors"
+	"fmt"
+	"time"
+)
+
+import (
+	"github.com/Workiva/go-datastructures/queue"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+type forkingClusterInvoker struct {
+	baseClusterInvoker
+}
+
+func newForkingClusterInvoker(directory cluster.Directory) protocol.Invoker {
+	return &forkingClusterInvoker{
+		baseClusterInvoker: newBaseClusterInvoker(directory),
+	}
+}
+
+func (invoker *forkingClusterInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+	err := invoker.checkWhetherDestroyed()
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	invokers := invoker.directory.List(invocation)
+	err = invoker.checkInvokers(invokers, invocation)
+	if err != nil {
+		return &protocol.RPCResult{Err: err}
+	}
+
+	var selected []protocol.Invoker
+	forks := int(invoker.GetUrl().GetParamInt(constant.FORKS_KEY, constant.DEFAULT_FORKS))
+	timeouts := invoker.GetUrl().GetParamInt(constant.TIMEOUT_KEY, constant.DEFAULT_TIMEOUT)
+	if forks < 0 || forks > len(invokers) {
+		selected = invokers
+	} else {
+		selected = make([]protocol.Invoker, 0)
+		loadbalance := getLoadBalance(invokers[0], invocation)
+		for i := 0; i < forks; i++ {
+			ivk := invoker.doSelect(loadbalance, invocation, invokers, selected)
+			if ivk != nil {
+				selected = append(selected, ivk)
+			}
+		}
+	}
+
+	resultQ := queue.New(1)
+	for _, ivk := range selected {
+		go func(k protocol.Invoker) {
+			result := k.Invoke(invocation)
+			err := resultQ.Put(result)
+			if err != nil {
+				logger.Errorf("resultQ put failed with exception: %v.\n", err)
+			}
+		}(ivk)
+	}
+
+	rsps, err := resultQ.Poll(1, time.Millisecond*time.Duration(timeouts))
+	if err != nil {
+		return &protocol.RPCResult{
+			Err: errors.New(fmt.Sprintf("failed to forking invoke provider %v, but no luck to perform the invocation. Last error is: %s", selected, err.Error()))}
+	}
+	if len(rsps) == 0 {
+		return &protocol.RPCResult{Err: errors.New(fmt.Sprintf("failed to forking invoke provider %v, but no resp", selected))}
+	}
+	result, ok := rsps[0].(protocol.Result)
+	if !ok {
+		return &protocol.RPCResult{Err: errors.New(fmt.Sprintf("failed to forking invoke provider %v, but not legal resp", selected))}
+	}
+	return result
+}
diff --git a/cluster/cluster_impl/forking_cluster_test.go b/cluster/cluster_impl/forking_cluster_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8603f8aedc4e28a3a4ca2f115355debc1a5ecc62
--- /dev/null
+++ b/cluster/cluster_impl/forking_cluster_test.go
@@ -0,0 +1,162 @@
+/*
+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 cluster_impl
+
+import (
+	"context"
+	"strconv"
+	"sync"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/cluster/directory"
+	"github.com/apache/dubbo-go/cluster/loadbalance"
+	"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/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/protocol/mock"
+)
+
+var (
+	forkingUrl, _ = common.NewURL(context.TODO(), "dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")
+)
+
+func registerForking(t *testing.T, mockInvokers ...*mock.MockInvoker) protocol.Invoker {
+	extension.SetLoadbalance(loadbalance.RoundRobin, loadbalance.NewRoundRobinLoadBalance)
+
+	invokers := []protocol.Invoker{}
+	for i, ivk := range mockInvokers {
+		invokers = append(invokers, ivk)
+		if i == 0 {
+			ivk.EXPECT().GetUrl().Return(forkingUrl)
+		}
+	}
+	staticDir := directory.NewStaticDirectory(invokers)
+
+	forkingCluster := NewForkingCluster()
+	clusterInvoker := forkingCluster.Join(staticDir)
+	return clusterInvoker
+}
+
+func Test_ForkingInvokeSuccess(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invokers := make([]*mock.MockInvoker, 0)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	forkingUrl.AddParam(constant.FORKS_KEY, strconv.Itoa(3))
+	//forkingUrl.AddParam(constant.TIMEOUT_KEY, strconv.Itoa(constant.DEFAULT_TIMEOUT))
+
+	var wg sync.WaitGroup
+	wg.Add(2)
+	for i := 0; i < 2; i++ {
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
+		invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
+			func(invocation protocol.Invocation) protocol.Result {
+				wg.Done()
+				return mockResult
+			})
+	}
+
+	clusterInvoker := registerForking(t, invokers...)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Equal(t, mockResult, result)
+	wg.Wait()
+}
+
+func Test_ForkingInvokeTimeout(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invokers := make([]*mock.MockInvoker, 0)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	forkingUrl.AddParam(constant.FORKS_KEY, strconv.Itoa(3))
+
+	var wg sync.WaitGroup
+	wg.Add(2)
+	for i := 0; i < 2; i++ {
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
+		invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
+			func(invocation protocol.Invocation) protocol.Result {
+				time.Sleep(2 * time.Second)
+				wg.Done()
+				return mockResult
+			})
+	}
+
+	clusterInvoker := registerForking(t, invokers...)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.NotNil(t, result)
+	assert.NotNil(t, result.Error())
+	wg.Wait()
+}
+
+func Test_ForkingInvokeHalfTimeout(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	invokers := make([]*mock.MockInvoker, 0)
+
+	mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}}
+	forkingUrl.AddParam(constant.FORKS_KEY, strconv.Itoa(3))
+
+	var wg sync.WaitGroup
+	wg.Add(2)
+	for i := 0; i < 2; i++ {
+		invoker := mock.NewMockInvoker(ctrl)
+		invokers = append(invokers, invoker)
+		invoker.EXPECT().IsAvailable().Return(true).AnyTimes()
+		if i == 1 {
+			invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
+				func(invocation protocol.Invocation) protocol.Result {
+					wg.Done()
+					return mockResult
+				})
+		} else {
+			invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(
+				func(invocation protocol.Invocation) protocol.Result {
+					time.Sleep(2 * time.Second)
+					wg.Done()
+					return mockResult
+				})
+		}
+	}
+
+	clusterInvoker := registerForking(t, invokers...)
+
+	result := clusterInvoker.Invoke(&invocation.RPCInvocation{})
+	assert.Equal(t, mockResult, result)
+	wg.Wait()
+}
diff --git a/cluster/loadbalance/least_active.go b/cluster/loadbalance/least_active.go
index 695ca21b0ed53dcf94907223e4c222af17311db9..39c5620f02d607bb68430e17a206a1649ee31c54 100644
--- a/cluster/loadbalance/least_active.go
+++ b/cluster/loadbalance/least_active.go
@@ -1,14 +1,19 @@
-// Licensed 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.
+/*
+ * 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.
+ */
 
 // @author yiji@apache.org
 package loadbalance
diff --git a/cluster/loadbalance/least_active_test.go b/cluster/loadbalance/least_active_test.go
index c29a2092a19161d0dd75ee4098ee786b620880b0..7663ea3ce6252dcb7ddeaea92fb6bef8d95478d5 100644
--- a/cluster/loadbalance/least_active_test.go
+++ b/cluster/loadbalance/least_active_test.go
@@ -43,8 +43,7 @@ func TestLeastActiveByWeight(t *testing.T) {
 		invokers = append(invokers, protocol.NewBaseInvoker(url))
 	}
 
-	inv := new(invocation.RPCInvocation)
-	inv.SetMethod("test")
+	inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 	protocol.BeginCount(invokers[2].GetUrl(), inv.MethodName())
 
 	loop = 10000
diff --git a/cluster/loadbalance/random_test.go b/cluster/loadbalance/random_test.go
index 09d3d259a903693e9c0550965fc12d2089228662..ffe65d78ac61e5210d23e44c7f802597fed78f96 100644
--- a/cluster/loadbalance/random_test.go
+++ b/cluster/loadbalance/random_test.go
@@ -67,8 +67,7 @@ func Test_RandomlbSelectWeight(t *testing.T) {
 	urlParams.Set("methods.test."+constant.WEIGHT_KEY, "10000000000000")
 	urll, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.100:20000/com.ikurento.user.UserProvider"), common.WithParams(urlParams))
 	invokers = append(invokers, protocol.NewBaseInvoker(urll))
-	ivc := &invocation.RPCInvocation{}
-	ivc.SetMethod("test")
+	ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 
 	var selectedInvoker []protocol.Invoker
 	var selected float64
@@ -99,8 +98,7 @@ func Test_RandomlbSelectWarmup(t *testing.T) {
 	urlParams.Set(constant.REMOTE_TIMESTAMP_KEY, strconv.FormatInt(time.Now().Add(time.Minute*(-9)).Unix(), 10))
 	urll, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.100:20000/com.ikurento.user.UserProvider"), common.WithParams(urlParams))
 	invokers = append(invokers, protocol.NewBaseInvoker(urll))
-	ivc := &invocation.RPCInvocation{}
-	ivc.SetMethod("test")
+	ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
 
 	var selectedInvoker []protocol.Invoker
 	var selected float64
diff --git a/cluster/loadbalance/round_robin.go b/cluster/loadbalance/round_robin.go
index e173e211c3630f4d4786edc2c1a09709fd7bf0a1..075acac7cdc60086ececb7b655dee86ec5198369 100644
--- a/cluster/loadbalance/round_robin.go
+++ b/cluster/loadbalance/round_robin.go
@@ -1,15 +1,19 @@
-//
-// Licensed 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.
+/*
+ * 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 loadbalance
 
diff --git a/common/constant/default.go b/common/constant/default.go
index 717b93163e347d345651319440a4b0504d31c980..e5c92fad4d3aa569b57e90d59f38c68834f4dba9 100644
--- a/common/constant/default.go
+++ b/common/constant/default.go
@@ -30,11 +30,13 @@ const (
 )
 
 const (
-	DEFAULT_LOADBALANCE = "random"
-	DEFAULT_RETRIES     = 2
-	DEFAULT_PROTOCOL    = "dubbo"
-	DEFAULT_REG_TIMEOUT = "10s"
-	DEFAULT_CLUSTER     = "failover"
+	DEFAULT_LOADBALANCE    = "random"
+	DEFAULT_RETRIES        = 2
+	DEFAULT_PROTOCOL       = "dubbo"
+	DEFAULT_REG_TIMEOUT    = "10s"
+	DEFAULT_CLUSTER        = "failover"
+	DEFAULT_FAILBACK_TIMES = 3
+	DEFAULT_FAILBACK_TASKS = 100
 )
 
 const (
@@ -42,6 +44,8 @@ const (
 	PREFIX_DEFAULT_KEY        = "default."
 	DEFAULT_SERVICE_FILTERS   = "echo"
 	DEFAULT_REFERENCE_FILTERS = ""
+	GENERIC_REFERENCE_FILTERS = "generic"
+	GENERIC                   = "$invoke"
 	ECHO                      = "$echo"
 )
 
diff --git a/common/constant/key.go b/common/constant/key.go
index f045bc8e95dee22462f979210327a2236699559c..13d65eb6f8d64f808d736566f4cc18c05cb9b1b4 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -34,6 +34,8 @@ const (
 	ENABLED_KEY            = "enabled"
 	SIDE_KEY               = "side"
 	OVERRIDE_PROVIDERS_KEY = "providerAddresses"
+	BEAN_NAME_KEY = "bean.name"
+	GENERIC_KEY   = "generic"
 )
 
 const (
@@ -50,6 +52,10 @@ const (
 	WARMUP_KEY           = "warmup"
 	RETRIES_KEY          = "retries"
 	BEAN_NAME            = "bean.name"
+	FAIL_BACK_TASKS_KEY  = "failbacktasks"
+	FORKS_KEY            = "forks"
+	DEFAULT_FORKS        = 2
+	DEFAULT_TIMEOUT      = 1000
 )
 
 const (
@@ -91,3 +97,15 @@ const (
 	ProviderConfigPrefix  = "dubbo.provider."
 	ConsumerConfigPrefix  = "dubbo.consumer."
 )
+
+const (
+	NACOS_KEY                    = "nacos"
+	NACOS_DEFAULT_ROLETYPE       = 3
+	NACOS_CACHE_DIR_KEY          = "cacheDir"
+	NACOS_LOG_DIR_KEY            = "logDir"
+	NACOS_ENDPOINT               = "endpoint"
+	NACOS_SERVICE_NAME_SEPARATOR = ":"
+	NACOS_CATEGORY_KEY           = "category"
+	NACOS_PROTOCOL_KEY           = "protocol"
+	NACOS_PATH_KEY               = "path"
+)
diff --git a/version/version.go b/common/constant/version.go
similarity index 98%
rename from version/version.go
rename to common/constant/version.go
index b9a076e78cbf0c9c7b5172e1b30c84f60f250ea7..d4c6821e76894cbd82dc5fae09124263b5c6aa0f 100644
--- a/version/version.go
+++ b/common/constant/version.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package version
+package constant
 
 const (
 	Version = "2.6.0"
diff --git a/common/logger/logger.go b/common/logger/logger.go
index e8dd5a608b68c7cbde0d8c6b85c1601c847fea01..f41e95744f954da69b0e3695c97ba3389c69160a 100644
--- a/common/logger/logger.go
+++ b/common/logger/logger.go
@@ -85,8 +85,6 @@ func InitLog(logConfFile string) error {
 
 	InitLogger(conf)
 
-	// set getty log
-	getty.SetLogger(logger)
 	return nil
 }
 
@@ -112,9 +110,16 @@ func InitLogger(conf *zap.Config) {
 	}
 	zapLogger, _ := zapLoggerConfig.Build(zap.AddCallerSkip(1))
 	logger = zapLogger.Sugar()
+
+	// set getty log
+	getty.SetLogger(logger)
 }
 
 func SetLogger(log Logger) {
 	logger = log
 	getty.SetLogger(logger)
 }
+
+func GetLogger() Logger {
+	return logger
+}
diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go
index 96d42eb21152e64d170f50276bbce88e1bf8db69..1c079f6bca52bf8f6e8c5ebb168da82ab8ccb5f2 100644
--- a/common/proxy/proxy.go
+++ b/common/proxy/proxy.go
@@ -116,7 +116,9 @@ func (p *Proxy) Implement(v common.RPCService) {
 				}
 			}
 
-			inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, inArr, reply.Interface(), p.callBack, common.URL{}, nil)
+			inv = invocation_impl.NewRPCInvocationWithOptions(invocation_impl.WithMethodName(methodName),
+				invocation_impl.WithArguments(inArr), invocation_impl.WithReply(reply.Interface()),
+				invocation_impl.WithCallBack(p.callBack))
 
 			for k, value := range p.attachments {
 				inv.SetAttachments(k, value)
diff --git a/common/proxy/proxy_test.go b/common/proxy/proxy_test.go
index 1cc30457c3b021ec139b57fe764d6ac6b9104dbc..8c1c0295d05135095b5be35b5b2b16428691d7f2 100644
--- a/common/proxy/proxy_test.go
+++ b/common/proxy/proxy_test.go
@@ -43,21 +43,15 @@ type TestService struct {
 	Echo        func(interface{}, *interface{}) error
 }
 
-func (s *TestService) Service() string {
+func (s *TestService) Reference() string {
 	return "com.test.Path"
 }
-func (s *TestService) Version() string {
-	return ""
-}
 
 type TestServiceInt int
 
-func (s *TestServiceInt) Service() string {
+func (s *TestServiceInt) Reference() string {
 	return "com.test.TestServiceInt"
 }
-func (s *TestServiceInt) Version() string {
-	return ""
-}
 
 func TestProxy_Implement(t *testing.T) {
 
diff --git a/common/rpc_service.go b/common/rpc_service.go
index 0444f0c17e7e9d96d1563c72fde2fd62b81fb744..4741a6fa3c0daef97f044f639a5e64a38fe4a187 100644
--- a/common/rpc_service.go
+++ b/common/rpc_service.go
@@ -36,8 +36,7 @@ import (
 
 // rpc service interface
 type RPCService interface {
-	Service() string // Path InterfaceName
-	Version() string
+	Reference() string // rpc service id or reference id
 }
 
 // for lowercase func
@@ -149,7 +148,7 @@ func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error)
 		return "", perrors.New(s)
 	}
 
-	sname = rcvr.Service()
+	sname = rcvr.Reference()
 	if server := sm.GetService(protocol, sname); server != nil {
 		return "", perrors.New("service already defined: " + sname)
 	}
@@ -172,8 +171,8 @@ func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error)
 	return strings.TrimSuffix(methods, ","), nil
 }
 
-func (sm *serviceMap) UnRegister(protocol, serviceName string) error {
-	if protocol == "" || serviceName == "" {
+func (sm *serviceMap) UnRegister(protocol, serviceId string) error {
+	if protocol == "" || serviceId == "" {
 		return perrors.New("protocol or serviceName is nil")
 	}
 	sm.mutex.RLock()
@@ -182,16 +181,16 @@ func (sm *serviceMap) UnRegister(protocol, serviceName string) error {
 		sm.mutex.RUnlock()
 		return perrors.New("no services for " + protocol)
 	}
-	_, ok = svcs[serviceName]
+	_, ok = svcs[serviceId]
 	if !ok {
 		sm.mutex.RUnlock()
-		return perrors.New("no service for " + serviceName)
+		return perrors.New("no service for " + serviceId)
 	}
 	sm.mutex.RUnlock()
 
 	sm.mutex.Lock()
 	defer sm.mutex.Unlock()
-	delete(svcs, serviceName)
+	delete(svcs, serviceId)
 	delete(sm.serviceMap, protocol)
 
 	return nil
diff --git a/common/rpc_service_test.go b/common/rpc_service_test.go
index 4232c9d90bee5a48ed988fa5449c3acbaf64f100..7df039b905d3cc064c5d6d9404fc874cf693dac9 100644
--- a/common/rpc_service_test.go
+++ b/common/rpc_service_test.go
@@ -39,12 +39,9 @@ func (s *TestService) MethodTwo(arg1, arg2, arg3 interface{}) (interface{}, erro
 func (s *TestService) MethodThree() error {
 	return nil
 }
-func (s *TestService) Service() string {
+func (s *TestService) Reference() string {
 	return "com.test.Path"
 }
-func (s *TestService) Version() string {
-	return ""
-}
 func (s *TestService) MethodMapper() map[string]string {
 	return map[string]string{
 		"MethodTwo": "methodTwo",
@@ -65,22 +62,16 @@ func (s *testService) Method3(ctx context.Context, args []interface{}, rsp *stru
 func (s *testService) Method4(ctx context.Context, args []interface{}, rsp *struct{}) *testService {
 	return nil
 }
-func (s *testService) Service() string {
+func (s *testService) Reference() string {
 	return "com.test.Path"
 }
-func (s *testService) Version() string {
-	return ""
-}
 
 type TestService1 struct {
 }
 
-func (s *TestService1) Service() string {
+func (s *TestService1) Reference() string {
 	return "com.test.Path1"
 }
-func (s *TestService1) Version() string {
-	return ""
-}
 
 func TestServiceMap_Register(t *testing.T) {
 	// lowercase
@@ -181,7 +172,7 @@ func TestSuiteMethod(t *testing.T) {
 
 	// wrong number of in return
 	s1 := &testService{}
-	method, ok = reflect.TypeOf(s1).MethodByName("Version")
+	method, ok = reflect.TypeOf(s1).MethodByName("Reference")
 	assert.True(t, ok)
 	methodType = suiteMethod(method)
 	assert.Nil(t, methodType)
diff --git a/common/url.go b/common/url.go
index 64c4274e6adc74228f7e856e00e40bbe05dd1d2d..52472d463a0784b0cb45e667c92cfc38f89e83d0 100644
--- a/common/url.go
+++ b/common/url.go
@@ -28,6 +28,7 @@ import (
 	"net/url"
 	"strconv"
 	"strings"
+	"sync"
 )
 
 import (
@@ -67,11 +68,13 @@ func (t RoleType) Role() string {
 }
 
 type baseUrl struct {
-	Protocol     string
-	Location     string // ip+port
-	Ip           string
-	Port         string
-	Params       url.Values
+	Protocol string
+	Location string // ip+port
+	Ip       string
+	Port     string
+	Params   url.Values
+	//url.Values is not safe map, add to avoid concurrent map read and map write error
+	paramsLock   sync.Mutex
 	PrimitiveURL string
 	ctx          context.Context
 }
@@ -139,6 +142,11 @@ func WithPath(path string) option {
 	}
 }
 
+func WithLocation(location string) option {
+	return func(url *URL) {
+		url.Location = location
+	}
+}
 func NewURLWithOptions(opts ...option) *URL {
 	url := &URL{}
 	for _, opt := range opts {
@@ -238,7 +246,7 @@ func isMatchCategory(category1 string, category2 string) bool {
 	} else if strings.Contains(category2, constant.REMOVE_VALUE_PREFIX) {
 		return !strings.Contains(category2, constant.REMOVE_VALUE_PREFIX+category1)
 	} else {
-		strings.Contains(category2, category1)
+		return strings.Contains(category2, category1)
 	}
 }
 func (c URL) String() string {
@@ -298,14 +306,18 @@ func (c URL) Service() string {
 }
 
 func (c *URL) AddParam(key string, value string) {
+	c.paramsLock.Lock()
 	c.Params.Add(key, value)
+	c.paramsLock.Unlock()
 }
 
 func (c URL) GetParam(s string, d string) string {
 	var r string
+	c.paramsLock.Lock()
 	if r = c.Params.Get(s); r == "" {
 		r = d
 	}
+	c.paramsLock.Unlock()
 	return r
 }
 func (c URL) GetParamAndDecoded(key string) (string, error) {
diff --git a/config/base_config_test.go b/config/base_config_test.go
index 7676a11d025975b604ce3c493e7462a4bdba23f1..d07d983f64ed33fcac73f8430737dfb2f01c40c3 100644
--- a/config/base_config_test.go
+++ b/config/base_config_test.go
@@ -35,8 +35,8 @@ func Test_refresh(t *testing.T) {
 	c := &BaseConfig{}
 	mockMap := map[string]string{}
 	mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100"
-	mockMap["dubbo.reference.MockService.MockService.retries"] = "10"
-	mockMap["dubbo.MockService.MockService.GetUser.retries"] = "10"
+	mockMap["dubbo.reference.com.MockService.MockService.retries"] = "10"
+	mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
 	mockMap["dubbo.consumer.check"] = "false"
 	mockMap["dubbo.application.name"] = "dubbo"
 
@@ -88,7 +88,7 @@ func Test_refresh(t *testing.T) {
 		},
 		References: map[string]*ReferenceConfig{
 			"MockService": {
-				InterfaceName: "MockService",
+				InterfaceName: "com.MockService",
 				Protocol:      "mock",
 				Cluster:       "failover",
 				Loadbalance:   "random",
@@ -98,13 +98,14 @@ func Test_refresh(t *testing.T) {
 				Methods: []*MethodConfig{
 					{
 						InterfaceId:   "MockService",
-						InterfaceName: "MockService",
+						InterfaceName: "com.MockService",
 						Name:          "GetUser",
 						Retries:       2,
 						Loadbalance:   "random",
 					},
-					{InterfaceId: "MockService",
-						InterfaceName: "MockService",
+					{
+						InterfaceId:   "MockService",
+						InterfaceName: "com.MockService",
 						Name:          "GetUser1",
 						Retries:       2,
 						Loadbalance:   "random",
@@ -128,8 +129,8 @@ func Test_refreshProvider(t *testing.T) {
 	c := &BaseConfig{}
 	mockMap := map[string]string{}
 	mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100"
-	mockMap["dubbo.service.MockService.MockService.retries"] = "10"
-	mockMap["dubbo.MockService.MockService.GetUser.retries"] = "10"
+	mockMap["dubbo.service.com.MockService.MockService.retries"] = "10"
+	mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
 	mockMap["dubbo.consumer.check"] = "false"
 	mockMap["dubbo.application.name"] = "dubbo"
 	mockMap["dubbo.protocols.jsonrpc1.name"] = "jsonrpc"
@@ -183,7 +184,7 @@ func Test_refreshProvider(t *testing.T) {
 		},
 		Services: map[string]*ServiceConfig{
 			"MockService": {
-				InterfaceName: "MockService",
+				InterfaceName: "com.MockService",
 				Protocol:      "mock",
 				Cluster:       "failover",
 				Loadbalance:   "random",
@@ -193,13 +194,13 @@ func Test_refreshProvider(t *testing.T) {
 				Methods: []*MethodConfig{
 					{
 						InterfaceId:   "MockService",
-						InterfaceName: "MockService",
+						InterfaceName: "com.MockService",
 						Name:          "GetUser",
 						Retries:       2,
 						Loadbalance:   "random",
 					},
 					{InterfaceId: "MockService",
-						InterfaceName: "MockService",
+						InterfaceName: "com.MockService",
 						Name:          "GetUser1",
 						Retries:       2,
 						Loadbalance:   "random",
diff --git a/config/config_loader.go b/config/config_loader.go
index 86260c86734d88527ab03fede8286dd484953ba3..b033aced5365dc58b06887d95b15b24ec91980a9 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -28,7 +28,6 @@ import (
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/common/logger"
-	"github.com/apache/dubbo-go/version"
 )
 
 var (
@@ -46,11 +45,11 @@ func init() {
 
 	confConFile = os.Getenv(constant.CONF_CONSUMER_FILE_PATH)
 	confProFile = os.Getenv(constant.CONF_PROVIDER_FILE_PATH)
-	if errCon := consumerInit(confConFile); errCon != nil {
+	if errCon := ConsumerInit(confConFile); errCon != nil {
 		log.Printf("[consumerInit] %#v", errCon)
 		consumerConfig = nil
 	}
-	if errPro := providerInit(confProFile); errPro != nil {
+	if errPro := ProviderInit(confProFile); errPro != nil {
 		log.Printf("[providerInit] %#v", errPro)
 		providerConfig = nil
 	}
@@ -58,11 +57,6 @@ func init() {
 
 // Dubbo Init
 func Load() {
-	var (
-		refMap map[string]*ReferenceConfig
-		srvMap map[string]*ServiceConfig
-	)
-
 	// reference config
 	if consumerConfig == nil {
 		logger.Warnf("consumerConfig is nil!")
@@ -70,18 +64,20 @@ func Load() {
 		if err := configCenterRefreshConsumer(); err != nil {
 			logger.Errorf("[consumer config center refresh] %#v", err)
 		}
-		refMap = make(map[string]*ReferenceConfig)
-		for _, ref := range consumerConfig.References {
-			rpcService := GetConsumerService(ref.InterfaceName)
+		for key, ref := range consumerConfig.References {
+			if ref.Generic {
+				genericService := NewGenericService(key)
+				SetConsumerService(genericService)
+			}
+			rpcService := GetConsumerService(key)
 
 			if rpcService == nil {
-				logger.Warnf("%s is not exsist!", ref.InterfaceName)
+				logger.Warnf("%s is not exsist!", key)
 				continue
 			}
+			ref.id = key
 			ref.Refer()
 			ref.Implement(rpcService)
-			refMap[ref.InterfaceName] = ref
-
 		}
 		//wait for invoker is available, if wait over default 3s, then panic
 		var count int
@@ -97,7 +93,7 @@ func Load() {
 						checkok = false
 						count++
 						if count > maxWait {
-							panic(fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, version.Version))
+							panic(fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version))
 						}
 						time.Sleep(time.Second * 1)
 						break
@@ -121,18 +117,17 @@ func Load() {
 		if err := configCenterRefreshProvider(); err != nil {
 			logger.Errorf("[provider config center refresh] %#v", err)
 		}
-		srvMap = make(map[string]*ServiceConfig)
-		for _, svs := range providerConfig.Services {
-			rpcService := GetProviderService(svs.InterfaceName)
+		for key, svs := range providerConfig.Services {
+			rpcService := GetProviderService(key)
 			if rpcService == nil {
-				logger.Warnf("%s is not exsist!", svs.InterfaceName)
+				logger.Warnf("%s is not exsist!", key)
 				continue
 			}
+			svs.id = key
 			svs.Implement(rpcService)
 			if err := svs.Export(); err != nil {
-				panic(fmt.Sprintf("service %s export failed! ", svs.InterfaceName))
+				panic(fmt.Sprintf("service %s export failed! ", key))
 			}
-			srvMap[svs.InterfaceName] = svs
 		}
 	}
 }
@@ -144,5 +139,5 @@ func GetRPCService(name string) common.RPCService {
 
 // create rpc service for consumer
 func RPCService(service common.RPCService) {
-	providerConfig.Services[service.Service()].Implement(service)
+	consumerConfig.References[service.Reference()].Implement(service)
 }
diff --git a/config/config_loader_test.go b/config/config_loader_test.go
index cbdc397c283f1e7948b42bbdd59b4f4a985671a6..107fea0b1d737f7be92d3e0042b6eebb7add78ed 100644
--- a/config/config_loader_test.go
+++ b/config/config_loader_test.go
@@ -45,9 +45,9 @@ func TestConfigLoader(t *testing.T) {
 	assert.Nil(t, providerConfig)
 	assert.Equal(t, ProviderConfig{}, GetProviderConfig())
 
-	err = consumerInit(conPath)
+	err = ConsumerInit(conPath)
 	assert.NoError(t, err)
-	err = providerInit(proPath)
+	err = ProviderInit(proPath)
 	assert.NoError(t, err)
 
 	assert.NotNil(t, consumerConfig)
@@ -71,12 +71,12 @@ func TestLoad(t *testing.T) {
 
 	Load()
 
-	assert.Equal(t, ms, GetRPCService(ms.Service()))
+	assert.Equal(t, ms, GetRPCService(ms.Reference()))
 	ms2 := &struct {
 		MockService
 	}{}
 	RPCService(ms2)
-	assert.NotEqual(t, ms2, GetRPCService(ms2.Service()))
+	assert.NotEqual(t, ms2, GetRPCService(ms2.Reference()))
 
 	conServices = map[string]common.RPCService{}
 	proServices = map[string]common.RPCService{}
@@ -84,6 +84,7 @@ func TestLoad(t *testing.T) {
 	consumerConfig = nil
 	providerConfig = nil
 }
+
 func TestWithNoRegLoad(t *testing.T) {
 	doInit()
 	doinit()
@@ -99,12 +100,12 @@ func TestWithNoRegLoad(t *testing.T) {
 
 	Load()
 
-	assert.Equal(t, ms, GetRPCService(ms.Service()))
+	assert.Equal(t, ms, GetRPCService(ms.Reference()))
 	ms2 := &struct {
 		MockService
 	}{}
 	RPCService(ms2)
-	assert.NotEqual(t, ms2, GetRPCService(ms2.Service()))
+	assert.NotEqual(t, ms2, GetRPCService(ms2.Reference()))
 
 	conServices = map[string]common.RPCService{}
 	proServices = map[string]common.RPCService{}
@@ -112,6 +113,7 @@ func TestWithNoRegLoad(t *testing.T) {
 	consumerConfig = nil
 	providerConfig = nil
 }
+
 func TestConfigLoaderWithConfigCenter(t *testing.T) {
 	extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory {
 		return &config_center.MockDynamicConfigurationFactory{}
@@ -127,10 +129,10 @@ func TestConfigLoaderWithConfigCenter(t *testing.T) {
 	assert.Nil(t, providerConfig)
 	assert.Equal(t, ProviderConfig{}, GetProviderConfig())
 
-	err = consumerInit(conPath)
+	err = ConsumerInit(conPath)
 	configCenterRefreshConsumer()
 	assert.NoError(t, err)
-	err = providerInit(proPath)
+	err = ProviderInit(proPath)
 	configCenterRefreshProvider()
 	assert.NoError(t, err)
 
diff --git a/config/consumer_config.go b/config/consumer_config.go
index 5d3aec18e91ab3d9284c00fac3838d16414f2755..737339a0ad195201327eb4fac3445b18eb4bbf26 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -61,6 +61,7 @@ func (*ConsumerConfig) Prefix() string {
 func SetConsumerConfig(c ConsumerConfig) {
 	consumerConfig = &c
 }
+
 func GetConsumerConfig() ConsumerConfig {
 	if consumerConfig == nil {
 		logger.Warnf("consumerConfig is nil!")
@@ -69,7 +70,7 @@ func GetConsumerConfig() ConsumerConfig {
 	return *consumerConfig
 }
 
-func consumerInit(confConFile string) error {
+func ConsumerInit(confConFile string) error {
 	if confConFile == "" {
 		return perrors.Errorf("application configure(consumer) file name is nil")
 	}
diff --git a/config/generic_service.go b/config/generic_service.go
new file mode 100644
index 0000000000000000000000000000000000000000..8a4e88df9788554bc4a5ee33884166e4ccede37f
--- /dev/null
+++ b/config/generic_service.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
+
+type GenericService struct {
+	Invoke       func(req []interface{}) (interface{}, error) `dubbo:"$invoke"`
+	referenceStr string
+}
+
+func NewGenericService(referenceStr string) *GenericService {
+	return &GenericService{referenceStr: referenceStr}
+}
+
+func (u *GenericService) Reference() string {
+	return u.referenceStr
+}
diff --git a/config/mock_rpcservice.go b/config/mock_rpcservice.go
index 0b3b9f22b497c66067eff5969b8dca044a34735a..64d431ffb6dfbc7e25a988c6093cf0ab5cbd2db5 100644
--- a/config/mock_rpcservice.go
+++ b/config/mock_rpcservice.go
@@ -23,14 +23,10 @@ import (
 
 type MockService struct{}
 
-func (*MockService) Service() string {
+func (*MockService) Reference() string {
 	return "MockService"
 }
 
-func (*MockService) Version() string {
-	return "1.0"
-}
-
 func (*MockService) GetUser(ctx context.Context, itf []interface{}, str *struct{}) error {
 	return nil
 }
diff --git a/config/provider_config.go b/config/provider_config.go
index fc7a4d50d2ede6c3a64dade9c90914e3b5d51779..a504eea237dc47f66c4ed27d334ce5eea5c87d45 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -63,7 +63,7 @@ func GetProviderConfig() ProviderConfig {
 	return *providerConfig
 }
 
-func providerInit(confProFile string) error {
+func ProviderInit(confProFile string) error {
 	if len(confProFile) == 0 {
 		return perrors.Errorf("application configure(provider) file name is nil")
 	}
diff --git a/config/reference_config.go b/config/reference_config.go
index 835d17f0549045008a996a5756bb3dd772782612..f90e3aabd3a68b8dc7a7509331d301ea3a252f92 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -38,6 +38,7 @@ import (
 type ReferenceConfig struct {
 	context       context.Context
 	pxy           *proxy.Proxy
+	id            string
 	InterfaceName string            `required:"true"  yaml:"interface"  json:"interface,omitempty" property:"interface"`
 	Check         *bool             `yaml:"check"  json:"check,omitempty" property:"check"`
 	Url           string            `yaml:"url"  json:"url,omitempty" property:"url"`
@@ -54,14 +55,16 @@ type ReferenceConfig struct {
 	Params        map[string]string `yaml:"params"  json:"params,omitempty" property:"params"`
 	invoker       protocol.Invoker
 	urls          []*common.URL
+	Generic       bool `yaml:"generic"  json:"generic,omitempty" property:"generic"`
 }
 
 func (c *ReferenceConfig) Prefix() string {
 	return constant.ReferenceConfigPrefix + c.InterfaceName + "."
 }
 
-func NewReferenceConfig(ctx context.Context) *ReferenceConfig {
-	return &ReferenceConfig{context: ctx}
+// The only way to get a new ReferenceConfig
+func NewReferenceConfig(id string, ctx context.Context) *ReferenceConfig {
+	return &ReferenceConfig{id: id, context: ctx}
 }
 
 func (refconfig *ReferenceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
@@ -76,7 +79,7 @@ func (refconfig *ReferenceConfig) UnmarshalYAML(unmarshal func(interface{}) erro
 }
 
 func (refconfig *ReferenceConfig) Refer() {
-	url := common.NewURLWithOptions(common.WithPath(refconfig.InterfaceName), common.WithProtocol(refconfig.Protocol), common.WithParams(refconfig.getUrlMap()))
+	url := common.NewURLWithOptions(common.WithPath(refconfig.id), common.WithProtocol(refconfig.Protocol), common.WithParams(refconfig.getUrlMap()))
 
 	//1. user specified URL, could be peer-to-peer address, or register center's address.
 	if refconfig.Url != "" {
@@ -91,7 +94,7 @@ func (refconfig *ReferenceConfig) Refer() {
 				refconfig.urls = append(refconfig.urls, &serviceUrl)
 			} else {
 				if serviceUrl.Path == "" {
-					serviceUrl.Path = "/" + refconfig.InterfaceName
+					serviceUrl.Path = "/" + refconfig.id
 				}
 				// merge url need to do
 				newUrl := common.MergeUrl(serviceUrl, url)
@@ -108,7 +111,6 @@ func (refconfig *ReferenceConfig) Refer() {
 			regUrl.SubURL = url
 		}
 	}
-
 	if len(refconfig.urls) == 1 {
 		refconfig.invoker = extension.GetProtocol(refconfig.urls[0].Protocol).Refer(*refconfig.urls[0])
 	} else {
@@ -155,6 +157,8 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	urlMap.Set(constant.RETRIES_KEY, strconv.FormatInt(refconfig.Retries, 10))
 	urlMap.Set(constant.GROUP_KEY, refconfig.Group)
 	urlMap.Set(constant.VERSION_KEY, refconfig.Version)
+	urlMap.Set(constant.GENERIC_KEY, strconv.FormatBool(refconfig.Generic))
+	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
 	//getty invoke async or sync
 	urlMap.Set(constant.ASYNC_KEY, strconv.FormatBool(refconfig.async))
 
@@ -168,7 +172,11 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	urlMap.Set(constant.ENVIRONMENT_KEY, consumerConfig.ApplicationConfig.Environment)
 
 	//filter
-	urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, constant.DEFAULT_REFERENCE_FILTERS))
+	var defaultReferenceFilter = constant.DEFAULT_REFERENCE_FILTERS
+	if refconfig.Generic {
+		defaultReferenceFilter = constant.GENERIC_REFERENCE_FILTERS + defaultReferenceFilter
+	}
+	urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, defaultReferenceFilter))
 
 	for _, v := range refconfig.Methods {
 		urlMap.Set("methods."+v.Name+"."+constant.LOADBALANCE_KEY, v.Loadbalance)
@@ -178,3 +186,11 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values {
 	return urlMap
 
 }
+func (refconfig *ReferenceConfig) GenericLoad(id string) {
+	genericService := NewGenericService(refconfig.id)
+	SetConsumerService(genericService)
+	refconfig.id = id
+	refconfig.Refer()
+	refconfig.Implement(genericService)
+	return
+}
diff --git a/config/reference_config_test.go b/config/reference_config_test.go
index 1a856872a63733866747a481e2a2e5d9295c46af..774fece29f5158b6840b3384b5c56846cc4da37b 100644
--- a/config/reference_config_test.go
+++ b/config/reference_config_test.go
@@ -20,6 +20,8 @@ package config
 import (
 	"sync"
 	"testing"
+
+	"github.com/apache/dubbo-go/common/constant"
 )
 
 import (
@@ -82,9 +84,10 @@ func doInit() {
 			"MockService": {
 				Params: map[string]string{
 					"serviceid": "soa.mock",
+					"forks":     "5",
 				},
 				Registry:      "shanghai_reg1,shanghai_reg2,hangzhou_reg1,hangzhou_reg2",
-				InterfaceName: "MockService",
+				InterfaceName: "com.MockService",
 				Protocol:      "mock",
 				Cluster:       "failover",
 				Loadbalance:   "random",
@@ -147,6 +150,7 @@ func Test_ReferP2P(t *testing.T) {
 	}
 	consumerConfig = nil
 }
+
 func Test_ReferMultiP2P(t *testing.T) {
 	doInit()
 	extension.SetProtocol("dubbo", GetProtocol)
@@ -189,6 +193,23 @@ func Test_Implement(t *testing.T) {
 	consumerConfig = nil
 }
 
+func Test_Forking(t *testing.T) {
+	doInit()
+	extension.SetProtocol("dubbo", GetProtocol)
+	extension.SetProtocol("registry", GetProtocol)
+	m := consumerConfig.References["MockService"]
+	m.Url = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000"
+
+	for _, reference := range consumerConfig.References {
+		reference.Refer()
+		forks := int(reference.invoker.GetUrl().GetParamInt(constant.FORKS_KEY, constant.DEFAULT_FORKS))
+		assert.Equal(t, 5, forks)
+		assert.NotNil(t, reference.pxy)
+		assert.NotNil(t, reference.Cluster)
+	}
+	consumerConfig = nil
+}
+
 func GetProtocol() protocol.Protocol {
 	if regProtocol != nil {
 		return regProtocol
diff --git a/config/registry_config.go b/config/registry_config.go
index 1a926b459e598ff313e141a39956dc88cb3daad3..0abdab810f3cfa835f7d1f21e395cd2a2812a051 100644
--- a/config/registry_config.go
+++ b/config/registry_config.go
@@ -36,9 +36,10 @@ type RegistryConfig struct {
 	TimeoutStr string `yaml:"timeout" default:"5s" json:"timeout,omitempty" property:"timeout"` // unit: second
 	Group      string `yaml:"group" json:"group,omitempty" property:"group"`
 	//for registry
-	Address  string `yaml:"address" json:"address,omitempty" property:"address"`
-	Username string `yaml:"username" json:"username,omitempty" property:"username"`
-	Password string `yaml:"password" json:"password,omitempty"  property:"password"`
+	Address  string            `yaml:"address" json:"address,omitempty" property:"address"`
+	Username string            `yaml:"username" json:"username,omitempty" property:"username"`
+	Password string            `yaml:"password" json:"password,omitempty"  property:"password"`
+	Params   map[string]string `yaml:"params" json:"params,omitempty" property:"params"`
 }
 
 func (*RegistryConfig) Prefix() string {
@@ -68,13 +69,28 @@ func loadRegistries(targetRegistries string, registries map[string]*RegistryConf
 		}
 
 		if target {
-			url, err := common.NewURL(
-				context.TODO(),
-				constant.REGISTRY_PROTOCOL+"://"+registryConf.Address,
-				common.WithParams(registryConf.getUrlMap(roleType)),
-				common.WithUsername(registryConf.Username),
-				common.WithPassword(registryConf.Password),
+			var (
+				url common.URL
+				err error
 			)
+			if addresses := strings.Split(registryConf.Address, ","); len(addresses) > 1 {
+				url, err = common.NewURL(
+					context.Background(),
+					constant.REGISTRY_PROTOCOL+"://"+addresses[0],
+					common.WithParams(registryConf.getUrlMap(roleType)),
+					common.WithUsername(registryConf.Username),
+					common.WithPassword(registryConf.Password),
+					common.WithLocation(registryConf.Address),
+				)
+			} else {
+				url, err = common.NewURL(
+					context.Background(),
+					constant.REGISTRY_PROTOCOL+"://"+registryConf.Address,
+					common.WithParams(registryConf.getUrlMap(roleType)),
+					common.WithUsername(registryConf.Username),
+					common.WithPassword(registryConf.Password),
+				)
+			}
 
 			if err != nil {
 				logger.Errorf("The registry id:%s url is invalid ,and will skip the registry, error: %#v", k, err)
@@ -94,6 +110,8 @@ func (regconfig *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values
 	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(int(roleType)))
 	urlMap.Set(constant.REGISTRY_KEY, regconfig.Protocol)
 	urlMap.Set(constant.REGISTRY_TIMEOUT_KEY, regconfig.TimeoutStr)
-
+	for k, v := range regconfig.Params {
+		urlMap.Set(k, v)
+	}
 	return urlMap
 }
diff --git a/config/registry_config_test.go b/config/registry_config_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f600a21a0117572349aaf4de1bdee5e1270f67b4
--- /dev/null
+++ b/config/registry_config_test.go
@@ -0,0 +1,61 @@
+/*
+ * 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 (
+	"fmt"
+	"testing"
+)
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_loadRegistries(t *testing.T) {
+	target := "shanghai1"
+	regs := map[string]*RegistryConfig{
+
+		"shanghai1": {
+			Protocol:   "mock",
+			TimeoutStr: "2s",
+			Group:      "shanghai_idc",
+			Address:    "127.0.0.2:2181,128.0.0.1:2181",
+			Username:   "user1",
+			Password:   "pwd1",
+		},
+	}
+	urls := loadRegistries(target, regs, common.CONSUMER)
+	fmt.Println(urls[0])
+	assert.Equal(t, "127.0.0.2:2181,128.0.0.1:2181", urls[0].Location)
+}
+func Test_loadRegistries1(t *testing.T) {
+	target := "shanghai1"
+	regs := map[string]*RegistryConfig{
+
+		"shanghai1": {
+			Protocol:   "mock",
+			TimeoutStr: "2s",
+			Group:      "shanghai_idc",
+			Address:    "127.0.0.2:2181",
+			Username:   "user1",
+			Password:   "pwd1",
+		},
+	}
+	urls := loadRegistries(target, regs, common.CONSUMER)
+	fmt.Println(urls[0])
+	assert.Equal(t, "127.0.0.2:2181", urls[0].Location)
+}
diff --git a/config/service.go b/config/service.go
index 0f3356f710dc89f25db102d73026e2bde9b9f466..2bceac4a8c20bb598dc2607c90c8206e4a448808 100644
--- a/config/service.go
+++ b/config/service.go
@@ -28,12 +28,12 @@ var (
 
 // SetConService is called by init() of implement of RPCService
 func SetConsumerService(service common.RPCService) {
-	conServices[service.Service()] = service
+	conServices[service.Reference()] = service
 }
 
 // SetProService is called by init() of implement of RPCService
 func SetProviderService(service common.RPCService) {
-	proServices[service.Service()] = service
+	proServices[service.Reference()] = service
 }
 
 func GetConsumerService(name string) common.RPCService {
diff --git a/config/service_config.go b/config/service_config.go
index 66386aec4e841f06478d3ee08d87c2c5f03487a8..5430f8a7c3c8702117cceefb10171e681a4f29d9 100644
--- a/config/service_config.go
+++ b/config/service_config.go
@@ -43,6 +43,7 @@ import (
 
 type ServiceConfig struct {
 	context       context.Context
+	id            string
 	Filter        string            `yaml:"filter" json:"filter,omitempty" property:"filter"`
 	Protocol      string            `required:"true"  yaml:"protocol"  json:"protocol,omitempty" property:"protocol"` //multi protocol support, split by ','
 	InterfaceName string            `required:"true"  yaml:"interface"  json:"interface,omitempty" property:"interface"`
@@ -66,8 +67,12 @@ func (c *ServiceConfig) Prefix() string {
 	return constant.ServiceConfigPrefix + c.InterfaceName + "."
 }
 
-func NewServiceConfig() *ServiceConfig {
+// The only way to get a new ServiceConfig
+func NewServiceConfig(id string, context context.Context) *ServiceConfig {
+
 	return &ServiceConfig{
+		context:    context,
+		id:         id,
 		unexported: atomic.NewBool(false),
 		exported:   atomic.NewBool(false),
 	}
@@ -99,15 +104,12 @@ func (srvconfig *ServiceConfig) Export() error {
 			logger.Errorf(err.Error())
 			return err
 		}
-		//contextPath := proto.ContextPath
-		//if contextPath == "" {
-		//	contextPath = providerConfig.Path
-		//}
-		url := common.NewURLWithOptions(common.WithPath(srvconfig.InterfaceName),
+		url := common.NewURLWithOptions(common.WithPath(srvconfig.id),
 			common.WithProtocol(proto.Name),
 			common.WithIp(proto.Ip),
 			common.WithPort(proto.Port),
 			common.WithParams(urlMap),
+			common.WithParamsValue(constant.BEAN_NAME_KEY, srvconfig.id),
 			common.WithMethods(strings.Split(methods, ",")))
 
 		if len(regUrls) > 0 {
@@ -158,6 +160,7 @@ func (srvconfig *ServiceConfig) getUrlMap() url.Values {
 	urlMap.Set(constant.RETRIES_KEY, strconv.FormatInt(srvconfig.Retries, 10))
 	urlMap.Set(constant.GROUP_KEY, srvconfig.Group)
 	urlMap.Set(constant.VERSION_KEY, srvconfig.Version)
+	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
 	//application info
 	urlMap.Set(constant.APPLICATION_KEY, providerConfig.ApplicationConfig.Name)
 	urlMap.Set(constant.ORGANIZATION_KEY, providerConfig.ApplicationConfig.Organization)
diff --git a/config/service_config_test.go b/config/service_config_test.go
index 4e0b7f95d6b156eeda021e3c02e5457e8b52b244..e111c8d110a14a039f3ab1a6c14f8044847f87e5 100644
--- a/config/service_config_test.go
+++ b/config/service_config_test.go
@@ -74,7 +74,7 @@ func doinit() {
 		},
 		Services: map[string]*ServiceConfig{
 			"MockService": {
-				InterfaceName: "MockService",
+				InterfaceName: "com.MockService",
 				Protocol:      "mock",
 				Registry:      "shanghai_reg1,shanghai_reg2,hangzhou_reg1,hangzhou_reg2",
 				Cluster:       "failover",
diff --git a/config/testdata/consumer_config.yml b/config/testdata/consumer_config.yml
index 68398623b6a2cbfe9fe9c255d3261c5a59b6af5e..372873abbb258e03acfe8e9e00d03aa2f77fb9a9 100644
--- a/config/testdata/consumer_config.yml
+++ b/config/testdata/consumer_config.yml
@@ -36,8 +36,10 @@ references:
     registry: "hangzhouzk,shanghaizk"
     filter: ""
     protocol : "dubbo"
+    version: "1.0"
+    group: "as"
     interface : "com.ikurento.user.UserProvider"
-    url: "dubbo://127.0.0.1:20000"
+    url: "dubbo://127.0.0.1:20000/UserProvider"
     cluster: "failover"
     methods :
       - name: "GetUser"
@@ -45,6 +47,7 @@ references:
     params:
       "serviceid":
         "soa.com.ikurento.user.UserProvider"
+      "forks": 5
 
 protocol_conf:
   dubbo:
@@ -52,9 +55,14 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
+    # gr_pool_size is recommended to be set to [cpu core number] * 100
+    gr_pool_size: 1200
+    # queue_len is recommended to be set to 64 or 128
+    queue_len: 64
+    # queue_number is recommended to be set to gr_pool_size / 20
+    queue_number: 60
     getty_session_param:
       compress_encoding: false
       tcp_no_delay: true
@@ -62,7 +70,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/config/testdata/consumer_config_with_configcenter.yml b/config/testdata/consumer_config_with_configcenter.yml
index df896d2442ce6eb5cf0cc41bb92f39964325d885..c6505e4492887cc6602ab0b2ee9a9fbd9fdce9c9 100644
--- a/config/testdata/consumer_config_with_configcenter.yml
+++ b/config/testdata/consumer_config_with_configcenter.yml
@@ -9,7 +9,7 @@ references:
     filter: ""
     protocol : "dubbo"
     interface : "com.ikurento.user.UserProvider"
-    url: "dubbo://127.0.0.1:20000"
+    url: "dubbo://127.0.0.1:20000/UserProvider"
     cluster: "failover"
     methods :
       - name: "GetUser"
@@ -21,7 +21,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
@@ -31,7 +30,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/config/testdata/provider_config.yml b/config/testdata/provider_config.yml
index 38952220e270b2b0a929a7583d1f5650ecab0121..e135860c208ff4d386a1abd658049e0e0aac73a3 100644
--- a/config/testdata/provider_config.yml
+++ b/config/testdata/provider_config.yml
@@ -33,6 +33,8 @@ services:
     # equivalent to interface of dubbo.xml
     interface : "com.ikurento.user.UserProvider"
     loadbalance: "random"
+    version: "1.0"
+    group: "as"
     warmup: "100"
     cluster: "failover"
     methods:
@@ -53,8 +55,13 @@ protocols:
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
+    # gr_pool_size is recommended to be set to [cpu core number] * 10
+    gr_pool_size: 120
+    # queue_len is recommended to be set to 64 or 128
+    queue_len: 64
+    # queue_number is recommended to be set to gr_pool_size / 20
+    queue_number: 6
     getty_session_param:
       compress_encoding: false
       tcp_no_delay: true
@@ -62,7 +69,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/config_center/zookeeper/impl.go b/config_center/zookeeper/impl.go
index ef0761efcd0d2cee47425dd5e1099200d3be6a70..f2827b2bb693fc1943116686f8056c0edaeadc99 100644
--- a/config_center/zookeeper/impl.go
+++ b/config_center/zookeeper/impl.go
@@ -196,7 +196,7 @@ func (r *zookeeperDynamicConfiguration) closeConfigs() {
 	r.cltLock.Lock()
 	defer r.cltLock.Unlock()
 	logger.Infof("begin to close provider zk client")
-	// 先关闭旧client,以关闭tmp node
+	// Close the old client first to close the tmp node
 	r.client.Close()
 	r.client = nil
 }
diff --git a/config_center/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar b/config_center/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar
deleted file mode 100644
index 839531b8b8762a9c19e334a5cbf79314cb16f945..0000000000000000000000000000000000000000
Binary files a/config_center/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar and /dev/null differ
diff --git a/dubbogo.png b/dubbogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..2cac434091276df102c3ae405c09621b8d8926ef
Binary files /dev/null and b/dubbogo.png differ
diff --git a/examples/dubbo/with-configcenter-go-client/app/client.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/client.go
similarity index 95%
rename from examples/dubbo/with-configcenter-go-client/app/client.go
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/client.go
index 867e17dc854a25c3a9b55de522053bc32c28a642..d27af7a31778403d518e6454de7ebab4b9b5cdf7 100644
--- a/examples/dubbo/with-configcenter-go-client/app/client.go
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/client.go
@@ -27,7 +27,7 @@ import (
 )
 
 import (
-	"github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
@@ -140,7 +140,7 @@ func initSignal() {
 				os.Exit(1)
 			})
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
+			// The program exits normally or timeout forcibly exits.
 			fmt.Println("app exit now...")
 			return
 		}
diff --git a/examples/dubbo/with-configcenter-go-client/app/user.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/user.go
similarity index 91%
rename from examples/dubbo/with-configcenter-go-client/app/user.go
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/user.go
index d491c3633384ad9ee6acdb2786d383e420f26db3..5bddf1e19f59be1b7fae917cffddfde4d362f44e 100644
--- a/examples/dubbo/with-configcenter-go-client/app/user.go
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/user.go
@@ -25,7 +25,7 @@ import (
 )
 
 import (
-	hessian "github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
@@ -83,7 +83,7 @@ type User struct {
 	Name string
 	Age  int32
 	Time time.Time
-	Sex  Gender // 注意此处,java enum Object <--> go string
+	Sex  Gender // notice: java enum Object <--> go string
 }
 
 func (u User) String() string {
@@ -108,10 +108,6 @@ type UserProvider struct {
 	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
 }
diff --git a/examples/dubbo/go-client/app/version.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/version.go
similarity index 100%
rename from examples/dubbo/go-client/app/version.go
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/version.go
diff --git a/examples/dubbo/go-client/assembly/bin/load.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/bin/load.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/bin/load.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/bin/load.sh
diff --git a/examples/dubbo/go-client/assembly/common/app.properties b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/app.properties
similarity index 100%
rename from examples/dubbo/go-client/assembly/common/app.properties
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/app.properties
diff --git a/examples/dubbo/go-client/assembly/common/build.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/build.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/common/build.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/build.sh
diff --git a/examples/dubbo/go-client/assembly/linux/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/dev.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/linux/dev.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/dev.sh
diff --git a/examples/dubbo/go-client/assembly/linux/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/release.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/linux/release.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/release.sh
diff --git a/examples/dubbo/go-client/assembly/linux/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/test.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/linux/test.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/test.sh
diff --git a/examples/dubbo/go-client/assembly/mac/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/dev.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/mac/dev.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/dev.sh
diff --git a/examples/dubbo/go-client/assembly/mac/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/release.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/mac/release.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/release.sh
diff --git a/examples/dubbo/go-client/assembly/mac/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/test.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/mac/test.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/test.sh
diff --git a/examples/dubbo/go-client/assembly/windows/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/dev.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/windows/dev.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/dev.sh
diff --git a/examples/dubbo/go-client/assembly/windows/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/release.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/windows/release.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/release.sh
diff --git a/examples/dubbo/go-client/assembly/windows/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/test.sh
similarity index 100%
rename from examples/dubbo/go-client/assembly/windows/test.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/test.sh
diff --git a/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml
similarity index 94%
rename from examples/dubbo/with-configcenter-go-client/profiles/test/client.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml
index c809041f14d15230a02f154571c02a038ee2ca92..c8e7bd0b053f797f3a5320451f08dcc590832330 100644
--- a/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml
@@ -21,7 +21,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
@@ -31,7 +30,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/dubbo/go-client/profiles/dev/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml
similarity index 100%
rename from examples/dubbo/go-client/profiles/dev/log.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml
diff --git a/examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/client.yml
similarity index 94%
rename from examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/client.yml
index c809041f14d15230a02f154571c02a038ee2ca92..c8e7bd0b053f797f3a5320451f08dcc590832330 100644
--- a/examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/client.yml
@@ -21,7 +21,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
@@ -31,7 +30,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/dubbo/go-client/profiles/release/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/log.yml
similarity index 100%
rename from examples/dubbo/go-client/profiles/release/log.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/log.yml
diff --git a/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/client.yml
similarity index 94%
rename from examples/dubbo/with-configcenter-go-client/profiles/release/client.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/client.yml
index c809041f14d15230a02f154571c02a038ee2ca92..c8e7bd0b053f797f3a5320451f08dcc590832330 100644
--- a/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/client.yml
@@ -21,7 +21,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
@@ -31,7 +30,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/dubbo/go-client/profiles/test/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml
similarity index 100%
rename from examples/dubbo/go-client/profiles/test/log.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml
diff --git a/examples/dubbo/with-configcenter-go-server/app/server.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go
similarity index 92%
rename from examples/dubbo/with-configcenter-go-server/app/server.go
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go
index d832ae8a29e5aff5dd487294b1b4dc37ba3a8036..cd982992171fdf674e560bfb4ed280c1951cccde 100644
--- a/examples/dubbo/with-configcenter-go-server/app/server.go
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go
@@ -26,7 +26,7 @@ import (
 )
 
 import (
-	hessian "github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
@@ -78,7 +78,7 @@ func initSignal() {
 				os.Exit(1)
 			})
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
+			// The program exits normally or timeout forcibly exits.
 			fmt.Println("provider app exit now...")
 			return
 		}
diff --git a/examples/dubbo/with-configcenter-go-server/app/user.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go
similarity index 93%
rename from examples/dubbo/with-configcenter-go-server/app/user.go
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go
index b84e7229cc62ce5b3c8e8b0a3927c55b2aff9df8..0e4d05766887ae41440313b49ba4dc859a09ed35 100644
--- a/examples/dubbo/with-configcenter-go-server/app/user.go
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go
@@ -25,13 +25,13 @@ import (
 )
 
 import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+	"github.com/apache/dubbo-go-hessian2/java_exception"
 	perrors "github.com/pkg/errors"
 )
 
 import (
 	"github.com/apache/dubbo-go/config"
-	hessian "github.com/dubbogo/hessian2"
-	"github.com/dubbogo/hessian2/java_exception"
 )
 
 type Gender hessian.JavaEnum
@@ -84,7 +84,7 @@ type (
 		Name string
 		Age  int32
 		Time time.Time
-		Sex  Gender // 注意此处,java enum Object <--> go string
+		Sex  Gender // notice: java enum Object <--> go string
 	}
 
 	UserProvider struct {
@@ -183,12 +183,8 @@ func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
 	return []interface{}{user, user1}, err
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
 }
 
 func println(format string, args ...interface{}) {
diff --git a/examples/dubbo/go-server/app/version.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
similarity index 100%
rename from examples/dubbo/go-server/app/version.go
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
diff --git a/examples/dubbo/go-server/assembly/bin/load.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/bin/load.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/bin/load.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/bin/load.sh
diff --git a/examples/dubbo/go-server/assembly/common/app.properties b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/app.properties
similarity index 100%
rename from examples/dubbo/go-server/assembly/common/app.properties
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/app.properties
diff --git a/examples/dubbo/go-server/assembly/common/build.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/build.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/common/build.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/build.sh
diff --git a/examples/dubbo/go-server/assembly/linux/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/dev.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/linux/dev.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/dev.sh
diff --git a/examples/dubbo/go-server/assembly/linux/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/release.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/linux/release.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/release.sh
diff --git a/examples/dubbo/go-server/assembly/linux/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/test.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/linux/test.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/test.sh
diff --git a/examples/dubbo/go-server/assembly/mac/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/dev.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/mac/dev.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/dev.sh
diff --git a/examples/dubbo/go-server/assembly/mac/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/release.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/mac/release.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/release.sh
diff --git a/examples/dubbo/go-server/assembly/mac/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/test.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/mac/test.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/test.sh
diff --git a/examples/dubbo/go-server/assembly/windows/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/dev.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/windows/dev.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/dev.sh
diff --git a/examples/dubbo/go-server/assembly/windows/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/release.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/windows/release.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/release.sh
diff --git a/examples/dubbo/go-server/assembly/windows/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/test.sh
similarity index 100%
rename from examples/dubbo/go-server/assembly/windows/test.sh
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/test.sh
diff --git a/examples/dubbo/go-server/profiles/dev/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/log.yml
similarity index 100%
rename from examples/dubbo/go-server/profiles/dev/log.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/log.yml
diff --git a/examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml
similarity index 94%
rename from examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml
index 05f758592f5aa69e097f19d14299e15bc9bf5f0f..cdaaca4c3803cf6126f00d67631dd1507d14505c 100644
--- a/examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml
@@ -23,7 +23,6 @@ services:
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
     getty_session_param:
       compress_encoding: false
@@ -32,7 +31,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/dubbo/go-server/profiles/release/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/log.yml
similarity index 100%
rename from examples/dubbo/go-server/profiles/release/log.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/log.yml
diff --git a/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/server.yml
similarity index 94%
rename from examples/dubbo/with-configcenter-go-server/profiles/release/server.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/server.yml
index 05f758592f5aa69e097f19d14299e15bc9bf5f0f..cdaaca4c3803cf6126f00d67631dd1507d14505c 100644
--- a/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/server.yml
@@ -23,7 +23,6 @@ services:
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
     getty_session_param:
       compress_encoding: false
@@ -32,7 +31,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/dubbo/go-server/profiles/test/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml
similarity index 100%
rename from examples/dubbo/go-server/profiles/test/log.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml
diff --git a/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml
similarity index 94%
rename from examples/dubbo/with-configcenter-go-server/profiles/test/server.yml
rename to examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml
index 05f758592f5aa69e097f19d14299e15bc9bf5f0f..cdaaca4c3803cf6126f00d67631dd1507d14505c 100644
--- a/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml
@@ -23,7 +23,6 @@ services:
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
     getty_session_param:
       compress_encoding: false
@@ -32,7 +31,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/jsonrpc/with-configcenter-go-client/app/client.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/client.go
similarity index 96%
rename from examples/jsonrpc/with-configcenter-go-client/app/client.go
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/client.go
index 642b45a9343477086300ccb78d56756fbf51a817..5b1634788c455f6b8f0fb964f25a07b525492cf0 100644
--- a/examples/jsonrpc/with-configcenter-go-client/app/client.go
+++ b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/client.go
@@ -125,7 +125,7 @@ func initSignal() {
 				os.Exit(1)
 			})
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
+			// The program exits normally or timeout forcibly exits.
 			fmt.Println("app exit now...")
 			return
 		}
diff --git a/examples/jsonrpc/with-configcenter-go-client/app/user.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/user.go
similarity index 93%
rename from examples/jsonrpc/with-configcenter-go-client/app/user.go
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/user.go
index ca98b1af0b3c1379c73623162546db9fb4fc95d6..fef665bb3d14709ffd584cbb184c18ffe8d87580 100644
--- a/examples/jsonrpc/with-configcenter-go-client/app/user.go
+++ b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/user.go
@@ -58,10 +58,6 @@ type UserProvider struct {
 	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
 }
diff --git a/examples/dubbo/with-configcenter-go-client/app/version.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/version.go
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/app/version.go
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/version.go
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/bin/load.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/bin/load.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/common/app.properties b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/app.properties
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/common/app.properties
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/app.properties
diff --git a/examples/jsonrpc/go-client/assembly/common/build.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/build.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/common/build.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/build.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/linux/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/linux/dev.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/linux/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/linux/release.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/linux/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/linux/test.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/mac/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/mac/dev.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/mac/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/mac/release.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/mac/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/mac/test.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/windows/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/windows/dev.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/windows/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/windows/release.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/windows/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/windows/test.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml
diff --git a/examples/dubbo/with-configcenter-go-client/profiles/dev/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/profiles/dev/log.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml
diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/release/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/client.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/profiles/release/client.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/client.yml
diff --git a/examples/dubbo/with-configcenter-go-client/profiles/release/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/log.yml
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/profiles/release/log.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/log.yml
diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/test/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/client.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/profiles/test/client.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/client.yml
diff --git a/examples/dubbo/with-configcenter-go-client/profiles/test/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/log.yml
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/profiles/test/log.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/log.yml
diff --git a/examples/jsonrpc/with-configcenter-go-server/app/server.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go
similarity index 94%
rename from examples/jsonrpc/with-configcenter-go-server/app/server.go
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go
index 851a97c15543961ad29784de449fe1ee56adc9c9..0a0e72915fef0ca4613f78a87fa1057152c1cc9a 100644
--- a/examples/jsonrpc/with-configcenter-go-server/app/server.go
+++ b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go
@@ -67,7 +67,7 @@ func initSignal() {
 				os.Exit(1)
 			})
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
+			// The program exits normally or timeout forcibly exits.
 			fmt.Println("provider app exit now...")
 			return
 		}
diff --git a/examples/jsonrpc/with-configcenter-go-server/app/user.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/user.go
similarity index 96%
rename from examples/jsonrpc/with-configcenter-go-server/app/user.go
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/user.go
index fbe6f3339c212d2bd42d52b6bbf7c7fcec6fb9c3..9ab9e58cb4d469dda347519674a8eef85b429fce 100644
--- a/examples/jsonrpc/with-configcenter-go-server/app/user.go
+++ b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/user.go
@@ -146,12 +146,8 @@ func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
 	return []User{*user, *user1}, err
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
 }
 
 func println(format string, args ...interface{}) {
diff --git a/examples/dubbo/with-configcenter-go-server/app/version.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/app/version.go
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/bin/load.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/bin/load.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/common/app.properties b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/app.properties
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/common/app.properties
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/app.properties
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/common/build.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/build.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/common/build.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/build.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/linux/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/linux/dev.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/linux/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/linux/release.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/linux/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/linux/test.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/mac/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/mac/dev.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/mac/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/mac/release.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/mac/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/mac/test.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/windows/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/windows/dev.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/windows/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/windows/release.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh
diff --git a/examples/dubbo/with-configcenter-go-server/assembly/windows/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/assembly/windows/test.sh
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh
diff --git a/examples/dubbo/with-configcenter-go-server/profiles/dev/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/profiles/dev/log.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml
diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml
diff --git a/examples/dubbo/with-configcenter-go-server/profiles/release/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/log.yml
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/profiles/release/log.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/log.yml
diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/release/server.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/server.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/profiles/release/server.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/server.yml
diff --git a/examples/dubbo/with-configcenter-go-server/profiles/test/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/log.yml
similarity index 100%
rename from examples/dubbo/with-configcenter-go-server/profiles/test/log.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/log.yml
diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/test/server.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/server.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/profiles/test/server.yml
rename to examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/server.yml
diff --git a/examples/dubbo/go-server/app/user.go b/examples/dubbo/go-server/app/user.go
deleted file mode 100644
index 3c261dc029022fe8a3a80a4007e5aa132643eb7c..0000000000000000000000000000000000000000
--- a/examples/dubbo/go-server/app/user.go
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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 main
-
-import (
-	"context"
-	"fmt"
-	"strconv"
-	"time"
-)
-
-import (
-	"github.com/dubbogo/hessian2"
-	"github.com/dubbogo/hessian2/java_exception"
-	perrors "github.com/pkg/errors"
-)
-
-import (
-	"github.com/apache/dubbo-go/config"
-)
-
-type Gender hessian.JavaEnum
-
-func init() {
-	config.SetProviderService(new(UserProvider))
-}
-
-const (
-	MAN hessian.JavaEnum = iota
-	WOMAN
-)
-
-var genderName = map[hessian.JavaEnum]string{
-	MAN:   "MAN",
-	WOMAN: "WOMAN",
-}
-
-var genderValue = map[string]hessian.JavaEnum{
-	"MAN":   MAN,
-	"WOMAN": WOMAN,
-}
-
-func (g Gender) JavaClassName() string {
-	return "com.ikurento.user.Gender"
-}
-
-func (g Gender) String() string {
-	s, ok := genderName[hessian.JavaEnum(g)]
-	if ok {
-		return s
-	}
-
-	return strconv.Itoa(int(g))
-}
-
-func (g Gender) EnumValue(s string) hessian.JavaEnum {
-	v, ok := genderValue[s]
-	if ok {
-		return v
-	}
-
-	return hessian.InvalidJavaEnum
-}
-
-type (
-	User struct {
-		// !!! Cannot define lowercase names of variable
-		Id   string
-		Name string
-		Age  int32
-		Time time.Time
-		Sex  Gender // 注意此处,java enum Object <--> go string
-	}
-
-	UserProvider struct {
-		user map[string]User
-	}
-)
-
-var (
-	DefaultUser = User{
-		Id: "0", Name: "Alex Stocks", Age: 31,
-		Sex: Gender(MAN),
-	}
-
-	userMap = UserProvider{user: make(map[string]User)}
-)
-
-func init() {
-	userMap.user["A000"] = DefaultUser
-	userMap.user["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, Sex: Gender(MAN)}
-	userMap.user["A002"] = User{Id: "002", Name: "Lily", Age: 20, Sex: Gender(WOMAN)}
-	userMap.user["A003"] = User{Id: "113", Name: "Moorse", Age: 30, Sex: Gender(WOMAN)}
-	for k, v := range userMap.user {
-		v.Time = time.Now()
-		userMap.user[k] = v
-	}
-}
-
-func (u User) String() string {
-	return fmt.Sprintf(
-		"User{Id:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
-		u.Id, u.Name, u.Age, u.Time, u.Sex,
-	)
-}
-
-func (u User) JavaClassName() string {
-	return "com.ikurento.user.User"
-}
-
-func (u *UserProvider) getUser(userId string) (*User, error) {
-	if user, ok := userMap.user[userId]; ok {
-		return &user, nil
-	}
-
-	return nil, fmt.Errorf("invalid user id:%s", userId)
-}
-
-func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
-	var (
-		err  error
-		user *User
-	)
-
-	println("req:%#v", req)
-	user, err = u.getUser(req[0].(string))
-	if err == nil {
-		*rsp = *user
-		println("rsp:%#v", rsp)
-	}
-	return err
-}
-
-func (u *UserProvider) GetUser0(id string, name string) (User, error) {
-	var err error
-
-	println("id:%s, name:%s", id, name)
-	user, err := u.getUser(id)
-	if err != nil {
-		return User{}, err
-	}
-	if user.Name != name {
-		return User{}, perrors.New("name is not " + user.Name)
-	}
-	return *user, err
-}
-
-func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
-	var err error
-
-	println("req:%#v", req)
-	rsp.Id = strconv.Itoa(int(req[0].(int32)))
-	return err
-}
-
-func (u *UserProvider) GetUser3() error {
-	return nil
-}
-
-func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
-	return java_exception.NewThrowable("exception")
-}
-
-func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
-	var err error
-
-	println("req:%s", req)
-	t := req[0].([]interface{})
-	user, err := u.getUser(t[0].(string))
-	if err != nil {
-		return nil, err
-	}
-	println("user:%v", user)
-	user1, err := u.getUser(t[1].(string))
-	if err != nil {
-		return nil, err
-	}
-	println("user1:%v", user1)
-
-	return []interface{}{user, user1}, err
-}
-
-func (s *UserProvider) MethodMapper() map[string]string {
-	return map[string]string{
-		"GetUser2": "getUser",
-	}
-}
-
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
-}
-
-func println(format string, args ...interface{}) {
-	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
-}
diff --git a/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
deleted file mode 100644
index edf4c0d2b20a08c17241132cd03bf16a51b2fbb8..0000000000000000000000000000000000000000
--- a/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// *****************************************************
-// DESC    : dubbo consumer
-// AUTHOR  : writtey by 包增辉(https://github.com/baozh)
-// VERSION : 1.0
-// LICENCE : Apache License 2.0
-// EMAIL   : alexstocks@foxmail.com
-// MOD     : 2016-10-19 17:03
-// FILE    : Consumer.java
-// ******************************************************
-
-package com.ikurento.user;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import com.alibaba.dubbo.rpc.service.EchoService;
-import java.util.List;
-
-public class Consumer {
-    //定义一个私有变量 (Spring中要求)
-    private UserProvider userProvider;
-
-    //Spring注入(Spring中要求)
-    public void setUserProvider(UserProvider u) {
-        this.userProvider = u;
-    }
-
-    private void benchmarkSayHello() {
-        for (int i = 0; i < Integer.MAX_VALUE; i ++) {
-            try {
-                // String hello = demoService.sayHello("world" + i);
-                // System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " + hello);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
-            // Thread.sleep(2000);
-        }
-    }
-
-    private void testGetUser() throws Exception {
-        try {
-            EchoService echoService = (EchoService)userProvider;
-            Object status = echoService.$echo("OK");
-            System.out.println("echo: "+status);
-            User user1 = userProvider.GetUser("A003");
-            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
-                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
-            User user2 = userProvider.GetUser0("A003","Moorse");
-            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                     " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
-                     + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
-            User user3 = userProvider.getUser(1);
-            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                     " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
-                     + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
-            userProvider.GetUser3();
-            System.out.println("GetUser3 succ");
-
-            User user9 = userProvider.GetUser1("A003");
-        } catch (Exception e) {
-            System.out.println("*************exception***********");
-            e.printStackTrace();
-        }
-        try {
-            userProvider.GetErr("A003");
-        } catch (Throwable t) {
-            System.out.println("*************exception***********");
-            t.printStackTrace();
-        }
-    }
-
-    private void testGetUsers() throws Exception {
-        try {
-            List<String> userIDList = new ArrayList<String>();
-            userIDList.add("A001");
-            userIDList.add("A002");
-            userIDList.add("A003");
-
-            List<User> userList = userProvider.GetUsers(userIDList);
-
-            for (int i = 0; i < userList.size(); i++) {
-                User user = userList.get(i);
-                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
-                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
-            }
-       } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    //启动consumer的入口函数(在配置文件中指定)
-    public void start() throws Exception {
-        testGetUser();
-        testGetUsers();
-//        Thread.sleep(120000);
-Thread.sleep(2000);
-    }
-}
diff --git a/examples/dubbo/go-client/app/client.go b/examples/general/dubbo/go-client/app/client.go
similarity index 51%
rename from examples/dubbo/go-client/app/client.go
rename to examples/general/dubbo/go-client/app/client.go
index 7918e2df0fbb2c488569791beefa6d872ca22564..e839b0b2776d8e3b2aba2756d2a622bea2b8e88d 100644
--- a/examples/dubbo/go-client/app/client.go
+++ b/examples/general/dubbo/go-client/app/client.go
@@ -25,16 +25,14 @@ import (
 	"syscall"
 	"time"
 )
-
 import (
-	"github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
 	"github.com/apache/dubbo-go/common/logger"
 	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
 	"github.com/apache/dubbo-go/config"
-	_ "github.com/apache/dubbo-go/protocol/dubbo"
 	_ "github.com/apache/dubbo-go/registry/protocol"
 
 	_ "github.com/apache/dubbo-go/filter/impl"
@@ -59,6 +57,44 @@ func main() {
 
 	config.Load()
 
+	println("\n\ntest")
+	test()
+	println("\n\ntest1")
+	test1()
+	println("\n\ntest2")
+	test2()
+	initSignal()
+}
+
+func initSignal() {
+	signals := make(chan os.Signal, 1)
+	// It is not possible to block SIGKILL or syscall.SIGSTOP
+	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
+		syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
+	for {
+		sig := <-signals
+		logger.Infof("get signal %s", sig.String())
+		switch sig {
+		case syscall.SIGHUP:
+			// reload()
+		default:
+			go time.AfterFunc(time.Duration(survivalTimeout), func() {
+				logger.Warnf("app exit now by force...")
+				os.Exit(1)
+			})
+
+			// The program exits normally or timeout forcibly exits.
+			fmt.Println("app exit now...")
+			return
+		}
+	}
+}
+
+func println(format string, args ...interface{}) {
+	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
+}
+
+func test() {
 	println("\n\n\necho")
 	res, err := userProvider.Echo(context.TODO(), "OK")
 	if err != nil {
@@ -109,43 +145,143 @@ func main() {
 	println("\n\n\nstart to test dubbo - getErr")
 	user = &User{}
 	err = userProvider.GetErr(context.TODO(), []interface{}{"A003"}, user)
-	if err != nil {
-		println("getErr - error: %v", err)
+	if err == nil {
+		panic("err is nil")
 	}
+	println("getErr - error: %v", err)
 
 	println("\n\n\nstart to test dubbo illegal method")
 	err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("error: %v", err)
+}
+
+func test1() {
+	println("\n\n\necho")
+	res, err := userProvider1.Echo(context.TODO(), "OK")
 	if err != nil {
 		panic(err)
 	}
+	println("res: %v\n", res)
 
-	initSignal()
-}
+	time.Sleep(3e9)
 
-func initSignal() {
-	signals := make(chan os.Signal, 1)
-	// It is not possible to block SIGKILL or syscall.SIGSTOP
-	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
-		syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
-	for {
-		sig := <-signals
-		logger.Infof("get signal %s", sig.String())
-		switch sig {
-		case syscall.SIGHUP:
-			// reload()
-		default:
-			go time.AfterFunc(time.Duration(survivalTimeout)*time.Second, func() {
-				logger.Warnf("app exit now by force...")
-				os.Exit(1)
-			})
+	println("\n\n\nstart to test dubbo")
+	user := &User{}
+	err = userProvider1.GetUser(context.TODO(), []interface{}{"A003"}, user)
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", user)
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
-			fmt.Println("app exit now...")
-			return
-		}
+	println("\n\n\nstart to test dubbo - GetUser0")
+	ret, err := userProvider1.GetUser0("A003", "Moorse")
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret)
+
+	println("\n\n\nstart to test dubbo - GetUsers")
+	ret1, err := userProvider1.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
+	if err != nil {
+		panic(err)
 	}
+	println("response result: %v", ret1)
+
+	println("\n\n\nstart to test dubbo - getUser")
+	user = &User{}
+	var i int32 = 1
+	err = userProvider1.GetUser2(context.TODO(), []interface{}{i}, user)
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", user)
+
+	println("\n\n\nstart to test dubbo - GetUser3")
+	err = userProvider1.GetUser3()
+	if err != nil {
+		panic(err)
+	}
+	println("succ!")
+
+	println("\n\n\nstart to test dubbo - getErr")
+	user = &User{}
+	err = userProvider1.GetErr(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("getErr - error: %v", err)
+
+	println("\n\n\nstart to test dubbo illegal method")
+	err = userProvider1.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("error: %v", err)
 }
 
-func println(format string, args ...interface{}) {
-	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
+func test2() {
+	println("\n\n\necho")
+	res, err := userProvider2.Echo(context.TODO(), "OK")
+	if err != nil {
+		panic(err)
+	}
+	println("res: %v\n", res)
+
+	time.Sleep(3e9)
+
+	println("\n\n\nstart to test dubbo")
+	user := &User{}
+	err = userProvider2.GetUser(context.TODO(), []interface{}{"A003"}, user)
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", user)
+
+	println("\n\n\nstart to test dubbo - GetUser0")
+	ret, err := userProvider2.GetUser0("A003", "Moorse")
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret)
+
+	println("\n\n\nstart to test dubbo - GetUsers")
+	ret1, err := userProvider2.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret1)
+
+	println("\n\n\nstart to test dubbo - getUser")
+	user = &User{}
+	var i int32 = 1
+	err = userProvider2.GetUser2(context.TODO(), []interface{}{i}, user)
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", user)
+
+	println("\n\n\nstart to test dubbo - GetUser3")
+	err = userProvider2.GetUser3()
+	if err != nil {
+		panic(err)
+	}
+	println("succ!")
+
+	println("\n\n\nstart to test dubbo - getErr")
+	user = &User{}
+	err = userProvider2.GetErr(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("getErr - error: %v", err)
+
+	println("\n\n\nstart to test dubbo illegal method")
+	err = userProvider2.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("error: %v", err)
 }
diff --git a/examples/dubbo/go-client/app/user.go b/examples/general/dubbo/go-client/app/user.go
similarity index 59%
rename from examples/dubbo/go-client/app/user.go
rename to examples/general/dubbo/go-client/app/user.go
index d491c3633384ad9ee6acdb2786d383e420f26db3..104d325d052940439da1c89c565a47520c73dd88 100644
--- a/examples/dubbo/go-client/app/user.go
+++ b/examples/general/dubbo/go-client/app/user.go
@@ -25,7 +25,7 @@ import (
 )
 
 import (
-	hessian "github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
@@ -34,10 +34,16 @@ import (
 
 type Gender hessian.JavaEnum
 
-var userProvider = new(UserProvider)
+var (
+	userProvider  = new(UserProvider)
+	userProvider1 = new(UserProvider1)
+	userProvider2 = new(UserProvider2)
+)
 
 func init() {
 	config.SetConsumerService(userProvider)
+	config.SetConsumerService(userProvider1)
+	config.SetConsumerService(userProvider2)
 }
 
 const (
@@ -83,7 +89,7 @@ type User struct {
 	Name string
 	Age  int32
 	Time time.Time
-	Sex  Gender // 注意此处,java enum Object <--> go string
+	Sex  Gender // notice: java enum Object <--> go string
 }
 
 func (u User) String() string {
@@ -108,10 +114,36 @@ type UserProvider struct {
 	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+type UserProvider1 struct {
+	GetUsers func(req []interface{}) ([]interface{}, error)
+	GetErr   func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser  func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser0 func(id string, name string) (User, error)
+	GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
+	GetUser3 func() error
+	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
+}
+
+func (u *UserProvider1) Reference() string {
+	return "UserProvider1"
+}
+
+type UserProvider2 struct {
+	GetUsers func(req []interface{}) ([]interface{}, error)
+	GetErr   func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser  func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser0 func(id string, name string) (User, error)
+	GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
+	GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
+	GetUser3 func() error
+	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider2) Reference() string {
+	return "UserProvider2"
 }
diff --git a/examples/jsonrpc/go-client/app/version.go b/examples/general/dubbo/go-client/app/version.go
similarity index 100%
rename from examples/jsonrpc/go-client/app/version.go
rename to examples/general/dubbo/go-client/app/version.go
diff --git a/examples/jsonrpc/go-client/assembly/bin/load.sh b/examples/general/dubbo/go-client/assembly/bin/load.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/bin/load.sh
rename to examples/general/dubbo/go-client/assembly/bin/load.sh
diff --git a/examples/jsonrpc/go-client/assembly/common/app.properties b/examples/general/dubbo/go-client/assembly/common/app.properties
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/common/app.properties
rename to examples/general/dubbo/go-client/assembly/common/app.properties
diff --git a/examples/dubbo/with-configcenter-go-client/assembly/common/build.sh b/examples/general/dubbo/go-client/assembly/common/build.sh
similarity index 100%
rename from examples/dubbo/with-configcenter-go-client/assembly/common/build.sh
rename to examples/general/dubbo/go-client/assembly/common/build.sh
diff --git a/examples/jsonrpc/go-client/assembly/linux/dev.sh b/examples/general/dubbo/go-client/assembly/linux/dev.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/linux/dev.sh
rename to examples/general/dubbo/go-client/assembly/linux/dev.sh
diff --git a/examples/jsonrpc/go-client/assembly/linux/release.sh b/examples/general/dubbo/go-client/assembly/linux/release.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/linux/release.sh
rename to examples/general/dubbo/go-client/assembly/linux/release.sh
diff --git a/examples/jsonrpc/go-client/assembly/linux/test.sh b/examples/general/dubbo/go-client/assembly/linux/test.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/linux/test.sh
rename to examples/general/dubbo/go-client/assembly/linux/test.sh
diff --git a/examples/jsonrpc/go-client/assembly/mac/dev.sh b/examples/general/dubbo/go-client/assembly/mac/dev.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/mac/dev.sh
rename to examples/general/dubbo/go-client/assembly/mac/dev.sh
diff --git a/examples/jsonrpc/go-client/assembly/mac/release.sh b/examples/general/dubbo/go-client/assembly/mac/release.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/mac/release.sh
rename to examples/general/dubbo/go-client/assembly/mac/release.sh
diff --git a/examples/jsonrpc/go-client/assembly/mac/test.sh b/examples/general/dubbo/go-client/assembly/mac/test.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/mac/test.sh
rename to examples/general/dubbo/go-client/assembly/mac/test.sh
diff --git a/examples/jsonrpc/go-client/assembly/windows/dev.sh b/examples/general/dubbo/go-client/assembly/windows/dev.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/windows/dev.sh
rename to examples/general/dubbo/go-client/assembly/windows/dev.sh
diff --git a/examples/jsonrpc/go-client/assembly/windows/release.sh b/examples/general/dubbo/go-client/assembly/windows/release.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/windows/release.sh
rename to examples/general/dubbo/go-client/assembly/windows/release.sh
diff --git a/examples/jsonrpc/go-client/assembly/windows/test.sh b/examples/general/dubbo/go-client/assembly/windows/test.sh
similarity index 100%
rename from examples/jsonrpc/go-client/assembly/windows/test.sh
rename to examples/general/dubbo/go-client/assembly/windows/test.sh
diff --git a/examples/general/dubbo/go-client/profiles/dev/client.yml b/examples/general/dubbo/go-client/profiles/dev/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ff696688416dc1e77f87d7831922894979d78da2
--- /dev/null
+++ b/examples/general/dubbo/go-client/profiles/dev/client.yml
@@ -0,0 +1,83 @@
+# dubbo client yaml configure file
+
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo user-info client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "dev"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "dubbo"
+    interface : "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods :
+    - name: "GetUser"
+      retries: 3
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+
+protocol_conf:
+  dubbo:
+    reconnect_interval: 0
+    connection_number: 2
+    heartbeat_period: "5s"
+    session_timeout: "20s"
+    pool_size: 64
+    pool_ttl: 600
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 10240
+      session_name: "client"
diff --git a/examples/jsonrpc/go-client/profiles/dev/log.yml b/examples/general/dubbo/go-client/profiles/dev/log.yml
similarity index 100%
rename from examples/jsonrpc/go-client/profiles/dev/log.yml
rename to examples/general/dubbo/go-client/profiles/dev/log.yml
diff --git a/examples/jsonrpc/go-client/profiles/dev/client.yml b/examples/general/dubbo/go-client/profiles/release/client.yml
similarity index 66%
rename from examples/jsonrpc/go-client/profiles/dev/client.yml
rename to examples/general/dubbo/go-client/profiles/release/client.yml
index 8d4346510fac9f7350b3d680b07a3d258b84e521..b4d897fda2b78e30dd912eab9f5a43bbcef9f595 100644
--- a/examples/jsonrpc/go-client/profiles/dev/client.yml
+++ b/examples/general/dubbo/go-client/profiles/release/client.yml
@@ -1,5 +1,6 @@
 # dubbo client yaml configure file
 
+
 check: true
 # client
 request_timeout : "3s"
@@ -8,12 +9,12 @@ connect_timeout : "3s"
 
 # application config
 application_config:
-    organization : "ikurento.com"
-    name  : "BDTService"
-    module : "dubbogo user-info client"
-    version : "0.0.1"
-    owner : "ZX"
-    environment : "dev"
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo user-info client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "release"
 
 registries :
   "hangzhouzk":
@@ -33,14 +34,31 @@ references:
   "UserProvider":
     # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
     registry: "hangzhouzk"
-    protocol : "jsonrpc"
-#    version : "2.0"
-#    group: "as"
+    protocol : "dubbo"
     interface : "com.ikurento.user.UserProvider"
     cluster: "failover"
     methods :
       - name: "GetUser"
         retries: 3
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
 
 protocol_conf:
   dubbo:
@@ -48,7 +66,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
@@ -58,7 +75,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/jsonrpc/go-client/profiles/release/log.yml b/examples/general/dubbo/go-client/profiles/release/log.yml
similarity index 100%
rename from examples/jsonrpc/go-client/profiles/release/log.yml
rename to examples/general/dubbo/go-client/profiles/release/log.yml
diff --git a/examples/general/dubbo/go-client/profiles/test/client.yml b/examples/general/dubbo/go-client/profiles/test/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c8b5c58691a0b35b55adb8f27cd1108433655b45
--- /dev/null
+++ b/examples/general/dubbo/go-client/profiles/test/client.yml
@@ -0,0 +1,83 @@
+# dubbo client yaml configure file
+
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo user-info client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "test"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "dubbo"
+    interface : "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods :
+    - name: "GetUser"
+      retries: 3
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+
+protocol_conf:
+  dubbo:
+    reconnect_interval: 0
+    connection_number: 2
+    heartbeat_period: "5s"
+    session_timeout: "20s"
+    pool_size: 64
+    pool_ttl: 600
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 10240
+      session_name: "client"
diff --git a/examples/jsonrpc/go-client/profiles/test/log.yml b/examples/general/dubbo/go-client/profiles/test/log.yml
similarity index 100%
rename from examples/jsonrpc/go-client/profiles/test/log.yml
rename to examples/general/dubbo/go-client/profiles/test/log.yml
diff --git a/examples/dubbo/go-server/app/app b/examples/general/dubbo/go-server/app/app
similarity index 100%
rename from examples/dubbo/go-server/app/app
rename to examples/general/dubbo/go-server/app/app
diff --git a/examples/dubbo/go-server/app/server.go b/examples/general/dubbo/go-server/app/server.go
similarity index 89%
rename from examples/dubbo/go-server/app/server.go
rename to examples/general/dubbo/go-server/app/server.go
index 788fc665b872d4f7f1429122cee581a6ab4979e7..ac92b879b15cb88ebc71fc5df90675b01760c899 100644
--- a/examples/dubbo/go-server/app/server.go
+++ b/examples/general/dubbo/go-server/app/server.go
@@ -26,7 +26,7 @@ import (
 )
 
 import (
-	hessian "github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 )
 
 import (
@@ -74,12 +74,12 @@ func initSignal() {
 		case syscall.SIGHUP:
 			// reload()
 		default:
-			go time.AfterFunc(time.Duration(float64(survivalTimeout)*float64(time.Second)), func() {
+			go time.AfterFunc(time.Duration(survivalTimeout), func() {
 				logger.Warnf("app exit now by force...")
 				os.Exit(1)
 			})
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
+			// The program exits normally or timeout forcibly exits.
 			fmt.Println("provider app exit now...")
 			return
 		}
diff --git a/examples/general/dubbo/go-server/app/user.go b/examples/general/dubbo/go-server/app/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..e07a02e772de589bd9df85ef6e1e69fb2468d347
--- /dev/null
+++ b/examples/general/dubbo/go-server/app/user.go
@@ -0,0 +1,113 @@
+/*
+ * 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 main
+
+import (
+	"fmt"
+	"strconv"
+	"time"
+)
+
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+type Gender hessian.JavaEnum
+
+const (
+	MAN hessian.JavaEnum = iota
+	WOMAN
+)
+
+var genderName = map[hessian.JavaEnum]string{
+	MAN:   "MAN",
+	WOMAN: "WOMAN",
+}
+
+var genderValue = map[string]hessian.JavaEnum{
+	"MAN":   MAN,
+	"WOMAN": WOMAN,
+}
+
+func (g Gender) JavaClassName() string {
+	return "com.ikurento.user.Gender"
+}
+
+func (g Gender) String() string {
+	s, ok := genderName[hessian.JavaEnum(g)]
+	if ok {
+		return s
+	}
+
+	return strconv.Itoa(int(g))
+}
+
+func (g Gender) EnumValue(s string) hessian.JavaEnum {
+	v, ok := genderValue[s]
+	if ok {
+		return v
+	}
+
+	return hessian.InvalidJavaEnum
+}
+
+type (
+	User struct {
+		// !!! Cannot define lowercase names of variable
+		Id   string
+		Name string
+		Age  int32
+		Time time.Time
+		Sex  Gender // notice: java enum Object <--> go string
+	}
+)
+
+var (
+	DefaultUser = User{
+		Id: "0", Name: "Alex Stocks", Age: 31,
+		Sex: Gender(MAN),
+	}
+
+	userMap = make(map[string]User)
+)
+
+func init() {
+	userMap["A000"] = DefaultUser
+	userMap["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, Sex: Gender(MAN)}
+	userMap["A002"] = User{Id: "002", Name: "Lily", Age: 20, Sex: Gender(WOMAN)}
+	userMap["A003"] = User{Id: "113", Name: "Moorse", Age: 30, Sex: Gender(WOMAN)}
+	for k, v := range userMap {
+		v.Time = time.Now()
+		userMap[k] = v
+	}
+}
+
+func (u User) String() string {
+	return fmt.Sprintf(
+		"User{Id:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
+		u.Id, u.Name, u.Age, u.Time, u.Sex,
+	)
+}
+
+func (u User) JavaClassName() string {
+	return "com.ikurento.user.User"
+}
+
+func println(format string, args ...interface{}) {
+	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
+}
diff --git a/examples/general/dubbo/go-server/app/user_provider.go b/examples/general/dubbo/go-server/app/user_provider.go
new file mode 100644
index 0000000000000000000000000000000000000000..fdf0a3abb2ac26cc2cbfa5971db3f02b18fe0be0
--- /dev/null
+++ b/examples/general/dubbo/go-server/app/user_provider.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+)
+
+import (
+	"github.com/apache/dubbo-go-hessian2/java_exception"
+	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider))
+}
+
+type UserProvider struct {
+}
+
+func (u *UserProvider) getUser(userId string) (*User, error) {
+	if user, ok := userMap[userId]; ok {
+		return &user, nil
+	}
+
+	return nil, fmt.Errorf("invalid user id:%s", userId)
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	var (
+		err  error
+		user *User
+	)
+
+	println("req:%#v", req)
+	user, err = u.getUser(req[0].(string))
+	if err == nil {
+		*rsp = *user
+		println("rsp:%#v", rsp)
+	}
+	return err
+}
+
+func (u *UserProvider) GetUser0(id string, name string) (User, error) {
+	var err error
+
+	println("id:%s, name:%s", id, name)
+	user, err := u.getUser(id)
+	if err != nil {
+		return User{}, err
+	}
+	if user.Name != name {
+		return User{}, perrors.New("name is not " + user.Name)
+	}
+	return *user, err
+}
+
+func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.Itoa(int(req[0].(int32)))
+	return err
+}
+
+func (u *UserProvider) GetUser3() error {
+	return nil
+}
+
+func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
+	return java_exception.NewThrowable("exception")
+}
+
+func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
+	var err error
+
+	println("req:%s", req)
+	t := req[0].([]interface{})
+	user, err := u.getUser(t[0].(string))
+	if err != nil {
+		return nil, err
+	}
+	println("user:%v", user)
+	user1, err := u.getUser(t[1].(string))
+	if err != nil {
+		return nil, err
+	}
+	println("user1:%v", user1)
+
+	return []interface{}{user, user1}, err
+}
+
+func (s *UserProvider) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
diff --git a/examples/general/dubbo/go-server/app/user_provider1.go b/examples/general/dubbo/go-server/app/user_provider1.go
new file mode 100644
index 0000000000000000000000000000000000000000..3edc816b592f9e165f149a792a9401a25c8c73c0
--- /dev/null
+++ b/examples/general/dubbo/go-server/app/user_provider1.go
@@ -0,0 +1,88 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+)
+
+import (
+	"github.com/apache/dubbo-go-hessian2/java_exception"
+	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider1))
+}
+
+type UserProvider1 struct {
+}
+
+func (u *UserProvider1) getUser(userId string) (*User, error) {
+	if user, ok := userMap[userId]; ok {
+		return &user, nil
+	}
+
+	return nil, fmt.Errorf("invalid user id:%s", userId)
+}
+
+func (u *UserProvider1) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	var (
+		err  error
+		user *User
+	)
+
+	println("req:%#v", req)
+	user, err = u.getUser(req[0].(string))
+	if err == nil {
+		*rsp = *user
+		println("rsp:%#v", rsp)
+	}
+	return err
+}
+
+func (u *UserProvider1) GetUser0(id string, name string) (User, error) {
+	var err error
+
+	println("id:%s, name:%s", id, name)
+	user, err := u.getUser(id)
+	if err != nil {
+		return User{}, err
+	}
+	if user.Name != name {
+		return User{}, perrors.New("name is not " + user.Name)
+	}
+	return *user, err
+}
+
+func (u *UserProvider1) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.Itoa(int(req[0].(int32)))
+	return err
+}
+
+func (u *UserProvider1) GetUser3() error {
+	return nil
+}
+
+func (u *UserProvider1) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
+	return java_exception.NewThrowable("exception")
+}
+
+func (u *UserProvider1) GetUsers(req []interface{}) ([]interface{}, error) {
+
+	return []interface{}{}, nil
+}
+
+func (s *UserProvider1) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
+func (u *UserProvider1) Reference() string {
+	return "UserProvider1"
+}
diff --git a/examples/general/dubbo/go-server/app/user_provider2.go b/examples/general/dubbo/go-server/app/user_provider2.go
new file mode 100644
index 0000000000000000000000000000000000000000..d28bcc33963ef73b372508e057679a5910948c25
--- /dev/null
+++ b/examples/general/dubbo/go-server/app/user_provider2.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+)
+
+import (
+	"github.com/apache/dubbo-go-hessian2/java_exception"
+	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider2))
+}
+
+type UserProvider2 struct {
+}
+
+func (u *UserProvider2) getUser(userId string) (*User, error) {
+	if user, ok := userMap[userId]; ok {
+		return &user, nil
+	}
+
+	return nil, fmt.Errorf("invalid user id:%s", userId)
+}
+
+func (u *UserProvider2) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	var (
+		err  error
+		user *User
+	)
+
+	println("req:%#v", req)
+	user, err = u.getUser(req[0].(string))
+	if err == nil {
+		*rsp = *user
+		println("rsp:%#v", rsp)
+	}
+	return err
+}
+
+func (u *UserProvider2) GetUser0(id string, name string) (User, error) {
+	var err error
+
+	println("id:%s, name:%s", id, name)
+	user, err := u.getUser(id)
+	if err != nil {
+		return User{}, err
+	}
+	if user.Name != name {
+		return User{}, perrors.New("name is not " + user.Name)
+	}
+	return *user, err
+}
+
+func (u *UserProvider2) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.Itoa(int(req[0].(int32)))
+	return err
+}
+
+func (u *UserProvider2) GetUser3() error {
+	return nil
+}
+
+func (u *UserProvider2) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
+	return java_exception.NewThrowable("exception")
+}
+
+func (u *UserProvider2) GetUsers(req []interface{}) ([]interface{}, error) {
+	var err error
+
+	println("req:%s", req)
+	t := req[0].([]interface{})
+	user, err := u.getUser(t[0].(string))
+	if err != nil {
+		return nil, err
+	}
+	println("user:%v", user)
+
+	return []interface{}{user}, err
+}
+
+func (s *UserProvider2) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
+func (u *UserProvider2) Reference() string {
+	return "UserProvider2"
+}
diff --git a/examples/jsonrpc/go-server/app/version.go b/examples/general/dubbo/go-server/app/version.go
similarity index 100%
rename from examples/jsonrpc/go-server/app/version.go
rename to examples/general/dubbo/go-server/app/version.go
diff --git a/examples/jsonrpc/go-server/assembly/bin/load.sh b/examples/general/dubbo/go-server/assembly/bin/load.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/bin/load.sh
rename to examples/general/dubbo/go-server/assembly/bin/load.sh
diff --git a/examples/jsonrpc/go-server/assembly/common/app.properties b/examples/general/dubbo/go-server/assembly/common/app.properties
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/common/app.properties
rename to examples/general/dubbo/go-server/assembly/common/app.properties
diff --git a/examples/jsonrpc/go-server/assembly/common/build.sh b/examples/general/dubbo/go-server/assembly/common/build.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/common/build.sh
rename to examples/general/dubbo/go-server/assembly/common/build.sh
diff --git a/examples/jsonrpc/go-server/assembly/linux/dev.sh b/examples/general/dubbo/go-server/assembly/linux/dev.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/linux/dev.sh
rename to examples/general/dubbo/go-server/assembly/linux/dev.sh
diff --git a/examples/jsonrpc/go-server/assembly/linux/release.sh b/examples/general/dubbo/go-server/assembly/linux/release.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/linux/release.sh
rename to examples/general/dubbo/go-server/assembly/linux/release.sh
diff --git a/examples/jsonrpc/go-server/assembly/linux/test.sh b/examples/general/dubbo/go-server/assembly/linux/test.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/linux/test.sh
rename to examples/general/dubbo/go-server/assembly/linux/test.sh
diff --git a/examples/jsonrpc/go-server/assembly/mac/dev.sh b/examples/general/dubbo/go-server/assembly/mac/dev.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/mac/dev.sh
rename to examples/general/dubbo/go-server/assembly/mac/dev.sh
diff --git a/examples/jsonrpc/go-server/assembly/mac/release.sh b/examples/general/dubbo/go-server/assembly/mac/release.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/mac/release.sh
rename to examples/general/dubbo/go-server/assembly/mac/release.sh
diff --git a/examples/jsonrpc/go-server/assembly/mac/test.sh b/examples/general/dubbo/go-server/assembly/mac/test.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/mac/test.sh
rename to examples/general/dubbo/go-server/assembly/mac/test.sh
diff --git a/examples/jsonrpc/go-server/assembly/windows/dev.sh b/examples/general/dubbo/go-server/assembly/windows/dev.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/windows/dev.sh
rename to examples/general/dubbo/go-server/assembly/windows/dev.sh
diff --git a/examples/jsonrpc/go-server/assembly/windows/release.sh b/examples/general/dubbo/go-server/assembly/windows/release.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/windows/release.sh
rename to examples/general/dubbo/go-server/assembly/windows/release.sh
diff --git a/examples/jsonrpc/go-server/assembly/windows/test.sh b/examples/general/dubbo/go-server/assembly/windows/test.sh
similarity index 100%
rename from examples/jsonrpc/go-server/assembly/windows/test.sh
rename to examples/general/dubbo/go-server/assembly/windows/test.sh
diff --git a/examples/jsonrpc/go-server/profiles/dev/log.yml b/examples/general/dubbo/go-server/profiles/dev/log.yml
similarity index 100%
rename from examples/jsonrpc/go-server/profiles/dev/log.yml
rename to examples/general/dubbo/go-server/profiles/dev/log.yml
diff --git a/examples/general/dubbo/go-server/profiles/dev/server.yml b/examples/general/dubbo/go-server/profiles/dev/server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..79c2cb2cc22a1b626a631009a0a4c6f29a8f9127
--- /dev/null
+++ b/examples/general/dubbo/go-server/profiles/dev/server.yml
@@ -0,0 +1,92 @@
+# dubbo server yaml configure file
+
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name : "BDTService"
+  module : "dubbogo user-info server"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "dev"
+
+registries :
+  "hangzhouzk":
+    # 对应java配置中address属性的zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+
+services:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "dubbo"
+    # 相当于dubbo.xml中的interface
+    interface : "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+
+protocols:
+  "dubbo1":
+    name: "dubbo"
+  #  ip : "127.0.0.1"
+    port: 20000
+
+
+protocol_conf:
+  dubbo:
+    session_number: 700
+    session_timeout: "20s"
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 1024
+      session_name: "server"
diff --git a/examples/jsonrpc/go-server/profiles/release/log.yml b/examples/general/dubbo/go-server/profiles/release/log.yml
similarity index 100%
rename from examples/jsonrpc/go-server/profiles/release/log.yml
rename to examples/general/dubbo/go-server/profiles/release/log.yml
diff --git a/examples/dubbo/go-server/profiles/dev/server.yml b/examples/general/dubbo/go-server/profiles/release/server.yml
similarity index 69%
rename from examples/dubbo/go-server/profiles/dev/server.yml
rename to examples/general/dubbo/go-server/profiles/release/server.yml
index bc4b288542322c8644c7af643dcb8dfafa099b1a..6890ed3bdb5048b02578ca8eba1620464378463c 100644
--- a/examples/dubbo/go-server/profiles/dev/server.yml
+++ b/examples/general/dubbo/go-server/profiles/release/server.yml
@@ -8,11 +8,10 @@ application_config:
   module : "dubbogo user-info server"
   version : "0.0.1"
   owner : "ZX"
-  environment : "dev"
+  environment : "release"
 
 registries :
   "hangzhouzk":
-    # 对应java配置中address属性的zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
     protocol: "zookeeper"
     timeout	: "3s"
     address: "127.0.0.1:2181"
@@ -27,7 +26,6 @@ registries :
 
 
 services:
-
   "UserProvider":
     # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
     registry: "hangzhouzk"
@@ -41,6 +39,31 @@ services:
       - name: "GetUser"
         retries: 1
         loadbalance: "random"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
 
 protocols:
   "dubbo1":
@@ -52,7 +75,6 @@ protocols:
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
     getty_session_param:
       compress_encoding: false
@@ -61,7 +83,6 @@ protocol_conf:
       keep_alive_period: "120s"
       tcp_r_buf_size: 262144
       tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
       pkg_wq_size: 512
       tcp_read_timeout: "1s"
       tcp_write_timeout: "5s"
diff --git a/examples/jsonrpc/go-server/profiles/test/log.yml b/examples/general/dubbo/go-server/profiles/test/log.yml
similarity index 100%
rename from examples/jsonrpc/go-server/profiles/test/log.yml
rename to examples/general/dubbo/go-server/profiles/test/log.yml
diff --git a/examples/general/dubbo/go-server/profiles/test/server.yml b/examples/general/dubbo/go-server/profiles/test/server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b6dd41da448d7531a3c5f4f24a8f460e5d1775bc
--- /dev/null
+++ b/examples/general/dubbo/go-server/profiles/test/server.yml
@@ -0,0 +1,91 @@
+# dubbo server yaml configure file
+
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name : "BDTService"
+  module : "dubbogo user-info server"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "test"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+
+services:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "dubbo"
+    # 相当于dubbo.xml中的interface
+    interface : "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "dubbo"
+    version: "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+
+protocols:
+  "dubbo1":
+    name: "dubbo"
+    #    ip : "127.0.0.1"
+    port: 20000
+
+
+protocol_conf:
+  dubbo:
+    session_number: 700
+    session_timeout: "20s"
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 1024
+      session_name: "server"
diff --git a/examples/dubbo/java-client/build.sh b/examples/general/dubbo/java-client/build.sh
similarity index 100%
rename from examples/dubbo/java-client/build.sh
rename to examples/general/dubbo/java-client/build.sh
diff --git a/examples/dubbo/java-client/pom.xml b/examples/general/dubbo/java-client/pom.xml
similarity index 100%
rename from examples/dubbo/java-client/pom.xml
rename to examples/general/dubbo/java-client/pom.xml
diff --git a/examples/dubbo/java-client/src/main/assembly/assembly.xml b/examples/general/dubbo/java-client/src/main/assembly/assembly.xml
similarity index 100%
rename from examples/dubbo/java-client/src/main/assembly/assembly.xml
rename to examples/general/dubbo/java-client/src/main/assembly/assembly.xml
diff --git a/examples/dubbo/java-client/src/main/assembly/conf/dubbo.properties b/examples/general/dubbo/java-client/src/main/assembly/conf/dubbo.properties
similarity index 100%
rename from examples/dubbo/java-client/src/main/assembly/conf/dubbo.properties
rename to examples/general/dubbo/java-client/src/main/assembly/conf/dubbo.properties
diff --git a/examples/dubbo/java-client/src/main/assembly/conf/log4j.properties b/examples/general/dubbo/java-client/src/main/assembly/conf/log4j.properties
similarity index 100%
rename from examples/dubbo/java-client/src/main/assembly/conf/log4j.properties
rename to examples/general/dubbo/java-client/src/main/assembly/conf/log4j.properties
diff --git a/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c9870eecacb51115b266e8e13d81e02323d5a74
--- /dev/null
+++ b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
@@ -0,0 +1,208 @@
+// *****************************************************
+// DESC    : dubbo consumer
+// AUTHOR  : writtey by 包增辉(https://github.com/baozh)
+// VERSION : 1.0
+// LICENCE : Apache License 2.0
+// EMAIL   : alexstocks@foxmail.com
+// MOD     : 2016-10-19 17:03
+// FILE    : Consumer.java
+// ******************************************************
+
+package com.ikurento.user;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import com.alibaba.dubbo.rpc.service.EchoService;
+import java.util.List;
+
+public class Consumer {
+    // Define a private variable (Required in Spring)
+    private UserProvider userProvider;
+    private UserProvider userProvider1;
+    private UserProvider userProvider2;
+
+    // Spring DI (Required in Spring)
+    public void setUserProvider(UserProvider u) {
+        this.userProvider = u;
+    }
+    public void setUserProvider1(UserProvider u) {
+        this.userProvider1 = u;
+    }
+    public void setUserProvider2(UserProvider u) {
+        this.userProvider2 = u;
+    }
+
+    // Start the entry function for consumer (Specified in the configuration file)
+    public void start() throws Exception {
+        System.out.println("\n\ntest");
+        testGetUser();
+        testGetUsers();
+        System.out.println("\n\ntest1");
+        testGetUser1();
+        testGetUsers1();
+        System.out.println("\n\ntest2");
+        testGetUser2();
+        testGetUsers2();
+        Thread.sleep(2000);
+    }
+
+    private void testGetUser() throws Exception {
+        try {
+            EchoService echoService = (EchoService)userProvider;
+            Object status = echoService.$echo("OK");
+            System.out.println("echo: "+status);
+            User user1 = userProvider.GetUser("A003");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
+                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
+            User user2 = userProvider.GetUser0("A003","Moorse");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
+                    + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                    + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
+            userProvider.GetUser3();
+            System.out.println("GetUser3 succ");
+
+            User user9 = userProvider.GetUser1("A003");
+        } catch (Exception e) {
+            System.out.println("*************exception***********");
+            e.printStackTrace();
+        }
+        try {
+            userProvider.GetErr("A003");
+        } catch (Throwable t) {
+            System.out.println("*************exception***********");
+            t.printStackTrace();
+        }
+    }
+
+    private void testGetUsers() throws Exception {
+        try {
+            List<String> userIDList = new ArrayList<String>();
+            userIDList.add("A001");
+            userIDList.add("A002");
+            userIDList.add("A003");
+
+            List<User> userList = userProvider.GetUsers(userIDList);
+
+            for (int i = 0; i < userList.size(); i++) {
+                User user = userList.get(i);
+                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
+                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUser1() throws Exception {
+        try {
+            EchoService echoService = (EchoService)userProvider1;
+            Object status = echoService.$echo("OK");
+            System.out.println("echo: "+status);
+            User user1 = userProvider1.GetUser("A003");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
+                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
+            User user2 = userProvider1.GetUser0("A003","Moorse");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
+                    + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider1.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                    + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
+            userProvider1.GetUser3();
+            System.out.println("GetUser3 succ");
+
+            User user9 = userProvider1.GetUser1("A003");
+        } catch (Exception e) {
+            System.out.println("*************exception***********");
+            e.printStackTrace();
+        }
+        try {
+            userProvider1.GetErr("A003");
+        } catch (Throwable t) {
+            System.out.println("*************exception***********");
+            t.printStackTrace();
+        }
+    }
+
+    private void testGetUsers1() throws Exception {
+        try {
+            List<String> userIDList = new ArrayList<String>();
+            userIDList.add("A001");
+            userIDList.add("A002");
+            userIDList.add("A003");
+
+            List<User> userList = userProvider1.GetUsers(userIDList);
+
+            for (int i = 0; i < userList.size(); i++) {
+                User user = userList.get(i);
+                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
+                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUser2() throws Exception {
+        try {
+            EchoService echoService = (EchoService)userProvider2;
+            Object status = echoService.$echo("OK");
+            System.out.println("echo: "+status);
+            User user1 = userProvider2.GetUser("A003");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
+                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
+            User user2 = userProvider2.GetUser0("A003","Moorse");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
+                    + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider2.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                    + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
+            userProvider2.GetUser3();
+            System.out.println("GetUser3 succ");
+
+            User user9 = userProvider2.GetUser1("A003");
+        } catch (Exception e) {
+            System.out.println("*************exception***********");
+            e.printStackTrace();
+        }
+        try {
+            userProvider2.GetErr("A003");
+        } catch (Throwable t) {
+            System.out.println("*************exception***********");
+            t.printStackTrace();
+        }
+    }
+
+    private void testGetUsers2() throws Exception {
+        try {
+            List<String> userIDList = new ArrayList<String>();
+            userIDList.add("A001");
+            userIDList.add("A002");
+            userIDList.add("A003");
+
+            List<User> userList = userProvider2.GetUsers(userIDList);
+
+            for (int i = 0; i < userList.size(); i++) {
+                User user = userList.get(i);
+                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
+                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/examples/dubbo/java-client/src/main/java/com/ikurento/user/Gender.java b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/Gender.java
similarity index 100%
rename from examples/dubbo/java-client/src/main/java/com/ikurento/user/Gender.java
rename to examples/general/dubbo/java-client/src/main/java/com/ikurento/user/Gender.java
diff --git a/examples/dubbo/java-client/src/main/java/com/ikurento/user/User.java b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/User.java
similarity index 100%
rename from examples/dubbo/java-client/src/main/java/com/ikurento/user/User.java
rename to examples/general/dubbo/java-client/src/main/java/com/ikurento/user/User.java
diff --git a/examples/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
similarity index 100%
rename from examples/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
rename to examples/general/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
diff --git a/examples/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
similarity index 84%
rename from examples/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
rename to examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
index 727007257fc5bb1e4d1aa73cfca8aa804a766e93..e7e5445a951614f599a63029f6d42508aaa4fccf 100644
--- a/examples/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
+++ b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
@@ -33,9 +33,12 @@
 	<dubbo:protocol id="jsonrpc" name="jsonrpc" />
 
 	<!-- 声明需要使用的服务接口 -->
-	<!--<dubbo:reference id="userProvider" protocol="jsonrpc" interface="com.ikurento.user.UserProvider">-->
 	<dubbo:reference registry="ikurento" check="false" id="userProvider" protocol="dubbo" interface="com.ikurento.user.UserProvider">
 		<!--<dubbo:parameter key="heartbeat" value="10000"/ -->
     </dubbo:reference>
 
+	<dubbo:reference registry="ikurento" check="false" id="userProvider1" protocol="dubbo" version="2.0" interface="com.ikurento.user.UserProvider">
+	</dubbo:reference>
+	<dubbo:reference registry="ikurento" check="false" id="userProvider2" protocol="dubbo" version="2.0" group="as" interface="com.ikurento.user.UserProvider">
+	</dubbo:reference>
 </beans>
diff --git a/examples/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
similarity index 90%
rename from examples/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml
rename to examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
index 625a879f97f5a21498be1efc1aa97fce68e76c61..db9fc3cba5a359b8835af53b81e50f8296d2e489 100644
--- a/examples/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml
+++ b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
@@ -24,6 +24,8 @@
 	<bean class="com.ikurento.user.Consumer" init-method="start">
 		<!-- 声明这个类 要使用的服务名-->
 		<property name="userProvider" ref="userProvider" />
+		<property name="userProvider1" ref="userProvider1" />
+		<property name="userProvider2" ref="userProvider2" />
 	</bean>
 
 	<!-- App config -->
diff --git a/examples/dubbo/java-client/src/main/resources/log4j.properties b/examples/general/dubbo/java-client/src/main/resources/log4j.properties
similarity index 100%
rename from examples/dubbo/java-client/src/main/resources/log4j.properties
rename to examples/general/dubbo/java-client/src/main/resources/log4j.properties
diff --git a/examples/dubbo/java-server/build.sh b/examples/general/dubbo/java-server/build.sh
similarity index 100%
rename from examples/dubbo/java-server/build.sh
rename to examples/general/dubbo/java-server/build.sh
diff --git a/examples/dubbo/java-server/pom.xml b/examples/general/dubbo/java-server/pom.xml
similarity index 100%
rename from examples/dubbo/java-server/pom.xml
rename to examples/general/dubbo/java-server/pom.xml
diff --git a/examples/dubbo/java-server/script/debug.sh b/examples/general/dubbo/java-server/script/debug.sh
similarity index 100%
rename from examples/dubbo/java-server/script/debug.sh
rename to examples/general/dubbo/java-server/script/debug.sh
diff --git a/examples/dubbo/java-server/src/main/assembly/assembly.xml b/examples/general/dubbo/java-server/src/main/assembly/assembly.xml
similarity index 100%
rename from examples/dubbo/java-server/src/main/assembly/assembly.xml
rename to examples/general/dubbo/java-server/src/main/assembly/assembly.xml
diff --git a/examples/dubbo/java-server/src/main/assembly/conf/dubbo.properties b/examples/general/dubbo/java-server/src/main/assembly/conf/dubbo.properties
similarity index 100%
rename from examples/dubbo/java-server/src/main/assembly/conf/dubbo.properties
rename to examples/general/dubbo/java-server/src/main/assembly/conf/dubbo.properties
diff --git a/examples/dubbo/java-server/src/main/assembly/conf/log4j.properties b/examples/general/dubbo/java-server/src/main/assembly/conf/log4j.properties
similarity index 100%
rename from examples/dubbo/java-server/src/main/assembly/conf/log4j.properties
rename to examples/general/dubbo/java-server/src/main/assembly/conf/log4j.properties
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/Gender.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/Gender.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/Gender.java
rename to examples/general/dubbo/java-server/src/main/java/com/ikurento/user/Gender.java
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java
rename to examples/general/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/Response.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/Response.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/Response.java
rename to examples/general/dubbo/java-server/src/main/java/com/ikurento/user/Response.java
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/User.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/User.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/User.java
rename to examples/general/dubbo/java-server/src/main/java/com/ikurento/user/User.java
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java
rename to examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java
diff --git a/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..04729fb7a33abe9738ccfdd48a7b2b19028587da
--- /dev/null
+++ b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
@@ -0,0 +1,121 @@
+package com.ikurento.user;
+//ref: https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+// import org.apache.log4j.Logger;
+// import org.apache.log4j.LoggerFactory;
+
+import java.util.*;
+
+public class UserProviderAnotherImpl implements UserProvider {
+    // private static final Logger logger = LoggerFactory.getLogger(getClass()); // Only output to dubbo's log(logs/server.log)
+    private static final Logger logger = LoggerFactory.getLogger("userLogger"); // Output to user-server.log
+
+    private Map<String, User> userMap = new HashMap<String, User>();
+
+    public UserProviderAnotherImpl() {
+        // userMap.put("001", new User("001", "other-zhangsan", 18, new Date(1998-1900, 1, 2, 3, 4, 5), Gender.MAN));
+        userMap.put("001", new User("001", "other-zhangsan", 18, new Date(0x12345678), Gender.MAN));
+        userMap.put("002", new User("002", "other-lisi", 20, new Date(1996-1900, 1, 2, 3, 4, 5), Gender.MAN));
+        userMap.put("003", new User("003", "other-lily", 23, new Date(1993-1900, 1, 2, 3, 4, 5), Gender.WOMAN));
+        userMap.put("004", new User("004", "other-lisa", 32, new Date(1985-1900, 1, 2, 3, 4, 5), Gender.WOMAN));
+    }
+
+    public boolean isLimit(Gender gender, String name) {
+        logger.info(String.format("input gender=%sand name=%s", gender, name));
+        return Gender.MAN == gender;
+    }
+
+    public User GetUser(String userId) {
+        logger.info("input userId = " + userId);
+        return new User(userId, "Joe", 48);
+    }
+
+    public User GetUser0(String userId, String name) {
+                return new User(userId, name, 48);
+    }
+    public void GetUser3() {
+    }
+    public User GetErr(String userId) throws Exception {
+        throw new Exception("exception");
+    }
+    public List<User> GetUsers(ArrayList<String> userIdList) {
+        Iterator it = userIdList.iterator();
+        List<User> userList = new ArrayList<User>();
+        logger.warn("@userIdList size:" + userIdList.size());
+
+        while(it.hasNext()) {
+            String id = (String)(it.next());
+            logger.info("GetUsers(@uid:" + id + ")");
+            if (userMap.containsKey(id)) {
+                userList.add(userMap.get(id));
+                logger.info("id:" + id + ", user:" + userMap.get(id));
+            }
+        }
+
+        return userList;
+    }
+
+    public Map<String, User> GetUserMap(List<String> userIdList) {
+        Iterator it = userIdList.iterator();
+        Map<String, User> map = new HashMap<String, User>();
+        logger.warn("@userIdList size:" + userIdList.size());
+
+        while(it.hasNext()) {
+            String id = (String)(it.next());
+            logger.info("GetUsers(@uid:" + id + ")");
+            if (userMap.containsKey(id)) {
+                map.put(id, userMap.get(id));
+                logger.info("id:" + id + ", user:" + userMap.get(id));
+            }
+        }
+
+        return map;
+    }
+
+    public List<User> GetUsers(List<String> userIdList) {
+        Iterator it = userIdList.iterator();
+        List<User> userList = new ArrayList<User>();
+        logger.warn("@userIdList size:" + userIdList.size());
+
+        while(it.hasNext()) {
+            String id = (String)(it.next());
+            logger.info("GetUsers(@uid:" + id + ")");
+            if (userMap.containsKey(id)) {
+                userList.add(userMap.get(id));
+                logger.info("id:" + id + ", user:" + userMap.get(id));
+            }
+        }
+
+        return userList;
+    }
+
+    // @Override
+    public User getUser(int userCode) {
+        logger.info("input userCode = " + userCode);
+        return new User(String.valueOf(userCode), "userCode get", 48);
+    }
+
+    public User queryUser(User user) {
+        logger.info("input user = " + user);
+        return new User(user.getId(), "get:" + user.getName(), user.getAge() + 18);
+    }
+
+    public Map<String, User> queryAll() {
+        logger.info("input");
+        Map<String, User> map = new HashMap<String, User>();
+        map.put("001", new User("001", "Joe", 18));
+        map.put("002", new User("002", "Wen", 20));
+
+        return map;
+    }
+
+    public int Calc(int a,int b) {
+        return a + b + 100;
+    }
+
+    public Response<Integer> Sum(int a,int b) {
+        return Response.ok(a+b);
+    }
+}
diff --git a/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..1efbf823740f5e3e4e82931a48bfc02ee9e78029
--- /dev/null
+++ b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
@@ -0,0 +1,100 @@
+package com.ikurento.user;
+
+// ref: https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Iterator;
+
+// import org.apache.log4j.Logger;
+// import org.apache.log4j.LoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserProviderImpl implements UserProvider {
+    // private static final Logger logger = LoggerFactory.getLogger(getClass()); // Only output to dubbo's log(logs/server.log)
+    private static final Logger LOG = LoggerFactory.getLogger("UserLogger"); // Output to user-server.log
+    Map<String, User> userMap = new HashMap<String, User>();
+
+    public UserProviderImpl() {
+        userMap.put("A001", new User("A001", "demo-zhangsan", 18));
+        userMap.put("A002", new User("A002", "demo-lisi", 20));
+        userMap.put("A003", new User("A003", "demo-lily", 23));
+        userMap.put("A004", new User("A004", "demo-lisa", 32));
+    }
+
+    public boolean isLimit(Gender gender, String name) {
+        return Gender.WOMAN == gender;
+    }
+
+    public User GetUser(String userId) {
+        return new User(userId, "zhangsan", 18);
+    }
+    public User GetErr(String userId) throws Exception {
+        throw new Exception("exception");
+    }
+    public User GetUser0(String userId, String name) {
+            return new User(userId, name, 18);
+    }
+
+    public List<User> GetUsers(List<String> userIdList) {
+        Iterator it = userIdList.iterator();
+        List<User> userList = new ArrayList<User>();
+        LOG.warn("@userIdList size:" + userIdList.size());
+
+        while(it.hasNext()) {
+            String id = (String)(it.next());
+            LOG.info("GetUsers(@uid:" + id + ")");
+            if (userMap.containsKey(id)) {
+                userList.add(userMap.get(id));
+                LOG.info("id:" + id + ", user:" + userMap.get(id));
+            }
+        }
+
+        return userList;
+    }
+
+    public void GetUser3() {
+    }
+
+    public Map<String, User> GetUserMap(List<String> userIdList) {
+        Iterator it = userIdList.iterator();
+        Map<String, User> map = new HashMap<String, User>();
+        LOG.warn("@userIdList size:" + userIdList.size());
+
+        while(it.hasNext()) {
+            String id = (String)(it.next());
+            LOG.info("GetUsers(@uid:" + id + ")");
+            if (userMap.containsKey(id)) {
+                map.put(id, userMap.get(id));
+                LOG.info("id:" + id + ", user:" + userMap.get(id));
+            }
+        }
+
+        return map;
+    }
+
+    public User queryUser(User user) {
+        return new User(user.getId(), "hello:" +user.getName(), user.getAge() + 18);
+    }
+
+    public Map<String, User> queryAll() {
+        return userMap;
+    }
+
+
+    public User getUser(int userCode) {
+        return new User(String.valueOf(userCode), "userCode get", 48);
+    }
+
+
+    public int Calc(int a,int b) {
+        return a + b;
+    }
+
+     public Response<Integer> Sum(int a,int b) {
+        return Response.ok(a+b);
+    }
+}
diff --git a/examples/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml b/examples/general/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
similarity index 100%
rename from examples/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
rename to examples/general/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
diff --git a/examples/dubbo/java-server/src/main/resources/log4j.properties b/examples/general/dubbo/java-server/src/main/resources/log4j.properties
similarity index 100%
rename from examples/dubbo/java-server/src/main/resources/log4j.properties
rename to examples/general/dubbo/java-server/src/main/resources/log4j.properties
diff --git a/examples/jsonrpc/go-client/app/client.go b/examples/general/jsonrpc/go-client/app/client.go
similarity index 53%
rename from examples/jsonrpc/go-client/app/client.go
rename to examples/general/jsonrpc/go-client/app/client.go
index 7a47e14bda652dbb4689bfe520bc163a2b0635dc..0d86275a8bfb46fdd0e3dfae91ea459d17012344 100644
--- a/examples/jsonrpc/go-client/app/client.go
+++ b/examples/general/jsonrpc/go-client/app/client.go
@@ -51,6 +51,45 @@ func main() {
 
 	config.Load()
 
+	println("\n\ntest")
+	test()
+	println("\n\ntest1")
+	test1()
+	println("\n\ntest2")
+	test2()
+
+	initSignal()
+}
+
+func initSignal() {
+	signals := make(chan os.Signal, 1)
+	// It is not possible to block SIGKILL or syscall.SIGSTOP
+	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
+		syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
+	for {
+		sig := <-signals
+		logger.Infof("get signal %s", sig.String())
+		switch sig {
+		case syscall.SIGHUP:
+		// reload()
+		default:
+			go time.AfterFunc(time.Duration(survivalTimeout), func() {
+				logger.Warnf("app exit now by force...")
+				os.Exit(1)
+			})
+
+			// The program exits normally or timeout forcibly exits.
+			fmt.Println("app exit now...")
+			return
+		}
+	}
+}
+
+func println(format string, args ...interface{}) {
+	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
+}
+
+func test() {
 	println("\n\n\necho")
 	res, err := userProvider.Echo(context.TODO(), "OK")
 	if err != nil {
@@ -100,37 +139,120 @@ func main() {
 
 	println("\n\n\nstart to test jsonrpc illegal method")
 	err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("error: %v", err)
+}
+
+func test1() {
+	println("\n\n\necho")
+	res, err := userProvider1.Echo(context.TODO(), "OK")
+	if err != nil {
+		println("echo - error: %v", err)
+	} else {
+		println("res: %v", res)
+	}
+
+	time.Sleep(3e9)
+
+	println("\n\n\nstart to test jsonrpc")
+	user := &JsonRPCUser{}
+	err = userProvider1.GetUser(context.TODO(), []interface{}{"A003"}, user)
 	if err != nil {
 		panic(err)
 	}
+	println("response result: %v", user)
 
-	initSignal()
-}
+	println("\n\n\nstart to test jsonrpc - GetUser0")
+	ret, err := userProvider1.GetUser0("A003", "Moorse")
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret)
 
-func initSignal() {
-	signals := make(chan os.Signal, 1)
-	// It is not possible to block SIGKILL or syscall.SIGSTOP
-	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
-		syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
-	for {
-		sig := <-signals
-		logger.Infof("get signal %s", sig.String())
-		switch sig {
-		case syscall.SIGHUP:
-		// reload()
-		default:
-			go time.AfterFunc(time.Duration(survivalTimeout)*time.Second, func() {
-				logger.Warnf("app exit now by force...")
-				os.Exit(1)
-			})
+	println("\n\n\nstart to test jsonrpc - GetUsers")
+	ret1, err := userProvider1.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret1)
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
-			fmt.Println("app exit now...")
-			return
-		}
+	println("\n\n\nstart to test jsonrpc - getUser")
+	user = &JsonRPCUser{}
+	err = userProvider1.GetUser2(context.TODO(), []interface{}{1}, user)
+	if err != nil {
+		panic(err)
 	}
+	println("response result: %v", user)
+
+	println("\n\n\nstart to test jsonrpc - GetUser3")
+	err = userProvider1.GetUser3()
+	if err != nil {
+		panic(err)
+	}
+	println("succ!")
+
+	println("\n\n\nstart to test jsonrpc illegal method")
+	err = userProvider1.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("error: %v", err)
 }
 
-func println(format string, args ...interface{}) {
-	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
+func test2() {
+	println("\n\n\necho")
+	res, err := userProvider2.Echo(context.TODO(), "OK")
+	if err != nil {
+		println("echo - error: %v", err)
+	} else {
+		println("res: %v", res)
+	}
+
+	time.Sleep(3e9)
+
+	println("\n\n\nstart to test jsonrpc")
+	user := &JsonRPCUser{}
+	err = userProvider2.GetUser(context.TODO(), []interface{}{"A003"}, user)
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", user)
+
+	println("\n\n\nstart to test jsonrpc - GetUser0")
+	ret, err := userProvider2.GetUser0("A003", "Moorse")
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret)
+
+	println("\n\n\nstart to test jsonrpc - GetUsers")
+	ret1, err := userProvider2.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", ret1)
+
+	println("\n\n\nstart to test jsonrpc - getUser")
+	user = &JsonRPCUser{}
+	err = userProvider2.GetUser2(context.TODO(), []interface{}{1}, user)
+	if err != nil {
+		panic(err)
+	}
+	println("response result: %v", user)
+
+	println("\n\n\nstart to test jsonrpc - GetUser3")
+	err = userProvider2.GetUser3()
+	if err != nil {
+		panic(err)
+	}
+	println("succ!")
+
+	println("\n\n\nstart to test jsonrpc illegal method")
+	err = userProvider2.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+	if err == nil {
+		panic("err is nil")
+	}
+	println("error: %v", err)
 }
diff --git a/examples/jsonrpc/go-client/app/user.go b/examples/general/jsonrpc/go-client/app/user.go
similarity index 55%
rename from examples/jsonrpc/go-client/app/user.go
rename to examples/general/jsonrpc/go-client/app/user.go
index ca98b1af0b3c1379c73623162546db9fb4fc95d6..c6fdbe13a8533c1bfb5ac4d442ef0c3ec968c298 100644
--- a/examples/jsonrpc/go-client/app/user.go
+++ b/examples/general/jsonrpc/go-client/app/user.go
@@ -27,10 +27,16 @@ import (
 	"github.com/apache/dubbo-go/config"
 )
 
-var userProvider = new(UserProvider)
+var (
+	userProvider  = new(UserProvider)
+	userProvider1 = new(UserProvider1)
+	userProvider2 = new(UserProvider2)
+)
 
 func init() {
 	config.SetConsumerService(userProvider)
+	config.SetConsumerService(userProvider1)
+	config.SetConsumerService(userProvider2)
 }
 
 type JsonRPCUser struct {
@@ -58,10 +64,34 @@ type UserProvider struct {
 	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+type UserProvider1 struct {
+	GetUsers func(req []interface{}) ([]JsonRPCUser, error)
+	GetUser  func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
+	GetUser0 func(id string, name string) (JsonRPCUser, error)
+	GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
+	GetUser2 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error `dubbo:"getUser"`
+	GetUser3 func() error
+	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
+}
+
+func (u *UserProvider1) Reference() string {
+	return "UserProvider1"
+}
+
+type UserProvider2 struct {
+	GetUsers func(req []interface{}) ([]JsonRPCUser, error)
+	GetUser  func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
+	GetUser0 func(id string, name string) (JsonRPCUser, error)
+	GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
+	GetUser2 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error `dubbo:"getUser"`
+	GetUser3 func() error
+	Echo     func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
 }
 
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider2) Reference() string {
+	return "UserProvider2"
 }
diff --git a/examples/jsonrpc/with-configcenter-go-client/app/version.go b/examples/general/jsonrpc/go-client/app/version.go
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/app/version.go
rename to examples/general/jsonrpc/go-client/app/version.go
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh b/examples/general/jsonrpc/go-client/assembly/bin/load.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh
rename to examples/general/jsonrpc/go-client/assembly/bin/load.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/common/app.properties b/examples/general/jsonrpc/go-client/assembly/common/app.properties
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/common/app.properties
rename to examples/general/jsonrpc/go-client/assembly/common/app.properties
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/common/build.sh b/examples/general/jsonrpc/go-client/assembly/common/build.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/common/build.sh
rename to examples/general/jsonrpc/go-client/assembly/common/build.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh b/examples/general/jsonrpc/go-client/assembly/linux/dev.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh
rename to examples/general/jsonrpc/go-client/assembly/linux/dev.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh b/examples/general/jsonrpc/go-client/assembly/linux/release.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh
rename to examples/general/jsonrpc/go-client/assembly/linux/release.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh b/examples/general/jsonrpc/go-client/assembly/linux/test.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh
rename to examples/general/jsonrpc/go-client/assembly/linux/test.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh b/examples/general/jsonrpc/go-client/assembly/mac/dev.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh
rename to examples/general/jsonrpc/go-client/assembly/mac/dev.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh b/examples/general/jsonrpc/go-client/assembly/mac/release.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh
rename to examples/general/jsonrpc/go-client/assembly/mac/release.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh b/examples/general/jsonrpc/go-client/assembly/mac/test.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh
rename to examples/general/jsonrpc/go-client/assembly/mac/test.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh b/examples/general/jsonrpc/go-client/assembly/windows/dev.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh
rename to examples/general/jsonrpc/go-client/assembly/windows/dev.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh b/examples/general/jsonrpc/go-client/assembly/windows/release.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh
rename to examples/general/jsonrpc/go-client/assembly/windows/release.sh
diff --git a/examples/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh b/examples/general/jsonrpc/go-client/assembly/windows/test.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh
rename to examples/general/jsonrpc/go-client/assembly/windows/test.sh
diff --git a/examples/general/jsonrpc/go-client/profiles/dev/client.yml b/examples/general/jsonrpc/go-client/profiles/dev/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..788e06eecd6014eefaf12913b6394e5e0a95efdf
--- /dev/null
+++ b/examples/general/jsonrpc/go-client/profiles/dev/client.yml
@@ -0,0 +1,60 @@
+# dubbo client yaml configure file
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo user-info client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "dev"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "jsonrpc"
+    interface : "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods :
+    - name: "GetUser"
+      retries: 3
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    version : "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    version : "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml b/examples/general/jsonrpc/go-client/profiles/dev/log.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml
rename to examples/general/jsonrpc/go-client/profiles/dev/log.yml
diff --git a/examples/jsonrpc/go-client/profiles/release/client.yml b/examples/general/jsonrpc/go-client/profiles/release/client.yml
similarity index 59%
rename from examples/jsonrpc/go-client/profiles/release/client.yml
rename to examples/general/jsonrpc/go-client/profiles/release/client.yml
index 3b82dd07bd0b41ace267721d151238c71beaa5a4..0084e5b04d48fea480f22df8e031eb91e1d6e835 100644
--- a/examples/jsonrpc/go-client/profiles/release/client.yml
+++ b/examples/general/jsonrpc/go-client/profiles/release/client.yml
@@ -34,34 +34,27 @@ references:
     # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
     registry: "hangzhouzk"
     protocol : "jsonrpc"
-#    version : "2.0"
-#    group: "as"
     interface : "com.ikurento.user.UserProvider"
     cluster: "failover"
     methods :
       - name: "GetUser"
         retries: 3
-
-protocol_conf:
-  dubbo:
-    reconnect_interval: 0
-    connection_number: 2
-    heartbeat_period: "5s"
-    session_timeout: "20s"
-    fail_fast_timeout: "5s"
-    pool_size: 64
-    pool_ttl: 600
-    getty_session_param:
-      compress_encoding: false
-      tcp_no_delay: true
-      tcp_keep_alive: true
-      keep_alive_period: "120s"
-      tcp_r_buf_size: 262144
-      tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
-      pkg_wq_size: 512
-      tcp_read_timeout: "1s"
-      tcp_write_timeout: "5s"
-      wait_timeout: "1s"
-      max_msg_len: 10240
-      session_name: "client"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    version : "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    version : "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/release/log.yml b/examples/general/jsonrpc/go-client/profiles/release/log.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/profiles/release/log.yml
rename to examples/general/jsonrpc/go-client/profiles/release/log.yml
diff --git a/examples/general/jsonrpc/go-client/profiles/test/client.yml b/examples/general/jsonrpc/go-client/profiles/test/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3efdedad4ab8acffb9d8724273deb8c12117837d
--- /dev/null
+++ b/examples/general/jsonrpc/go-client/profiles/test/client.yml
@@ -0,0 +1,60 @@
+# dubbo client yaml configure file
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo user-info client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "test"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "jsonrpc"
+    interface : "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods :
+    - name: "GetUser"
+      retries: 3
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    version : "2.0"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    version : "2.0"
+    group: "as"
+    interface: "com.ikurento.user.UserProvider"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 3
diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/test/log.yml b/examples/general/jsonrpc/go-client/profiles/test/log.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-client/profiles/test/log.yml
rename to examples/general/jsonrpc/go-client/profiles/test/log.yml
diff --git a/examples/jsonrpc/go-server/app/server.go b/examples/general/jsonrpc/go-server/app/server.go
similarity index 89%
rename from examples/jsonrpc/go-server/app/server.go
rename to examples/general/jsonrpc/go-server/app/server.go
index 8a226e23ad74960612ef1cfe2f82740a6e7516d8..e36b6efe9d115d8352f09f1f5011ea00d92f0d13 100644
--- a/examples/jsonrpc/go-server/app/server.go
+++ b/examples/general/jsonrpc/go-server/app/server.go
@@ -64,12 +64,12 @@ func initSignal() {
 		case syscall.SIGHUP:
 		// reload()
 		default:
-			go time.AfterFunc(time.Duration(float64(survivalTimeout)*float64(time.Second)), func() {
+			go time.AfterFunc(time.Duration(survivalTimeout), func() {
 				logger.Warnf("app exit now by force...")
 				os.Exit(1)
 			})
 
-			// 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
+			// The program exits normally or timeout forcibly exits.
 			fmt.Println("provider app exit now...")
 			return
 		}
diff --git a/examples/general/jsonrpc/go-server/app/user.go b/examples/general/jsonrpc/go-server/app/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..837661003e75f1d8c2d5442c756f45cb32f5d590
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/app/user.go
@@ -0,0 +1,78 @@
+/*
+ * 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 main
+
+import (
+	"fmt"
+	"time"
+)
+
+type Gender int
+
+const (
+	MAN = iota
+	WOMAN
+)
+
+var genderStrings = [...]string{
+	"MAN",
+	"WOMAN",
+}
+
+func (g Gender) String() string {
+	return genderStrings[g]
+}
+
+type (
+	User struct {
+		Id    string `json:"id"`
+		Name  string `json:"name"`
+		Age   int    `json:"age"`
+		sex   Gender
+		Birth int    `json:"time"`
+		Sex   string `json:"sex"`
+	}
+)
+
+var (
+	DefaultUser = User{
+		Id: "0", Name: "Alex Stocks", Age: 31,
+		// Birth: int(time.Date(1985, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
+		Birth: int(time.Date(1985, 11, 24, 15, 15, 0, 0, time.Local).Unix()),
+		sex:   Gender(MAN),
+	}
+
+	userMap = make(map[string]User)
+)
+
+func init() {
+	DefaultUser.Sex = DefaultUser.sex.String()
+	userMap["A000"] = DefaultUser
+	userMap["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, sex: MAN}
+	userMap["A002"] = User{Id: "002", Name: "Lily", Age: 20, sex: WOMAN}
+	userMap["A003"] = User{Id: "113", Name: "Moorse", Age: 30, sex: MAN}
+	for k, v := range userMap {
+		v.Birth = int(time.Now().AddDate(-1*v.Age, 0, 0).Unix())
+		v.Sex = userMap[k].sex.String()
+		userMap[k] = v
+	}
+}
+
+func println(format string, args ...interface{}) {
+	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
+}
diff --git a/examples/general/jsonrpc/go-server/app/user_provider.go b/examples/general/jsonrpc/go-server/app/user_provider.go
new file mode 100644
index 0000000000000000000000000000000000000000..4af4bb040484eb8613c50545e93312aa232f7de2
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/app/user_provider.go
@@ -0,0 +1,98 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+)
+
+import (
+	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider))
+}
+
+type UserProvider struct {
+}
+
+func (u *UserProvider) getUser(userId string) (*User, error) {
+	if user, ok := userMap[userId]; ok {
+		return &user, nil
+	}
+
+	return nil, fmt.Errorf("invalid user id:%s", userId)
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	var (
+		err  error
+		user *User
+	)
+
+	println("req:%#v", req)
+	user, err = u.getUser(req[0].(string))
+	if err == nil {
+		*rsp = *user
+		println("rsp:%#v", rsp)
+	}
+	return err
+}
+
+func (u *UserProvider) GetUser0(id string, name string) (User, error) {
+	var err error
+
+	println("id:%s, name:%s", id, name)
+	user, err := u.getUser(id)
+	if err != nil {
+		return User{}, err
+	}
+	if user.Name != name {
+		return User{}, perrors.New("name is not " + user.Name)
+	}
+	return *user, err
+}
+
+func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.FormatFloat(req[0].(float64), 'f', 0, 64)
+	rsp.Sex = Gender(MAN).String()
+	return err
+}
+
+func (u *UserProvider) GetUser3() error {
+	return nil
+}
+
+func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
+	var err error
+
+	println("req:%s", req)
+	t := req[0].([]interface{})
+	user, err := u.getUser(t[0].(string))
+	if err != nil {
+		return nil, err
+	}
+	println("user:%v", user)
+	user1, err := u.getUser(t[1].(string))
+	if err != nil {
+		return nil, err
+	}
+	println("user1:%v", user1)
+
+	return []User{*user, *user1}, err
+}
+
+func (s *UserProvider) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
diff --git a/examples/general/jsonrpc/go-server/app/user_provider1.go b/examples/general/jsonrpc/go-server/app/user_provider1.go
new file mode 100644
index 0000000000000000000000000000000000000000..1557c6b8d22c3e6969e8b48b87008576eb71a984
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/app/user_provider1.go
@@ -0,0 +1,83 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+)
+
+import (
+	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider1))
+}
+
+type UserProvider1 struct {
+}
+
+func (u *UserProvider1) getUser(userId string) (*User, error) {
+	if user, ok := userMap[userId]; ok {
+		return &user, nil
+	}
+
+	return nil, fmt.Errorf("invalid user id:%s", userId)
+}
+
+func (u *UserProvider1) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	var (
+		err  error
+		user *User
+	)
+
+	println("req:%#v", req)
+	user, err = u.getUser(req[0].(string))
+	if err == nil {
+		*rsp = *user
+		println("rsp:%#v", rsp)
+	}
+	return err
+}
+
+func (u *UserProvider1) GetUser0(id string, name string) (User, error) {
+	var err error
+
+	println("id:%s, name:%s", id, name)
+	user, err := u.getUser(id)
+	if err != nil {
+		return User{}, err
+	}
+	if user.Name != name {
+		return User{}, perrors.New("name is not " + user.Name)
+	}
+	return *user, err
+}
+
+func (u *UserProvider1) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.FormatFloat(req[0].(float64), 'f', 0, 64)
+	rsp.Sex = Gender(MAN).String()
+	return err
+}
+
+func (u *UserProvider1) GetUser3() error {
+	return nil
+}
+
+func (u *UserProvider1) GetUsers(req []interface{}) ([]User, error) {
+	return []User{}, nil
+}
+
+func (s *UserProvider1) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
+func (u *UserProvider1) Reference() string {
+	return "UserProvider1"
+}
diff --git a/examples/general/jsonrpc/go-server/app/user_provider2.go b/examples/general/jsonrpc/go-server/app/user_provider2.go
new file mode 100644
index 0000000000000000000000000000000000000000..7d2fb80a99763235610628865b4704a3999c489b
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/app/user_provider2.go
@@ -0,0 +1,93 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+)
+
+import (
+	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider2))
+}
+
+type UserProvider2 struct {
+}
+
+func (u *UserProvider2) getUser(userId string) (*User, error) {
+	if user, ok := userMap[userId]; ok {
+		return &user, nil
+	}
+
+	return nil, fmt.Errorf("invalid user id:%s", userId)
+}
+
+func (u *UserProvider2) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	var (
+		err  error
+		user *User
+	)
+
+	println("req:%#v", req)
+	user, err = u.getUser(req[0].(string))
+	if err == nil {
+		*rsp = *user
+		println("rsp:%#v", rsp)
+	}
+	return err
+}
+
+func (u *UserProvider2) GetUser0(id string, name string) (User, error) {
+	var err error
+
+	println("id:%s, name:%s", id, name)
+	user, err := u.getUser(id)
+	if err != nil {
+		return User{}, err
+	}
+	if user.Name != name {
+		return User{}, perrors.New("name is not " + user.Name)
+	}
+	return *user, err
+}
+
+func (u *UserProvider2) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.FormatFloat(req[0].(float64), 'f', 0, 64)
+	rsp.Sex = Gender(MAN).String()
+	return err
+}
+
+func (u *UserProvider2) GetUser3() error {
+	return nil
+}
+
+func (u *UserProvider2) GetUsers(req []interface{}) ([]User, error) {
+	var err error
+
+	println("req:%s", req)
+	t := req[0].([]interface{})
+	user, err := u.getUser(t[0].(string))
+	if err != nil {
+		return nil, err
+	}
+	println("user:%v", user)
+
+	return []User{*user}, err
+}
+
+func (s *UserProvider2) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
+func (u *UserProvider2) Reference() string {
+	return "UserProvider2"
+}
diff --git a/examples/jsonrpc/with-configcenter-go-server/app/version.go b/examples/general/jsonrpc/go-server/app/version.go
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/app/version.go
rename to examples/general/jsonrpc/go-server/app/version.go
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh b/examples/general/jsonrpc/go-server/assembly/bin/load.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh
rename to examples/general/jsonrpc/go-server/assembly/bin/load.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/common/app.properties b/examples/general/jsonrpc/go-server/assembly/common/app.properties
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/common/app.properties
rename to examples/general/jsonrpc/go-server/assembly/common/app.properties
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/common/build.sh b/examples/general/jsonrpc/go-server/assembly/common/build.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/common/build.sh
rename to examples/general/jsonrpc/go-server/assembly/common/build.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh b/examples/general/jsonrpc/go-server/assembly/linux/dev.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh
rename to examples/general/jsonrpc/go-server/assembly/linux/dev.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh b/examples/general/jsonrpc/go-server/assembly/linux/release.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh
rename to examples/general/jsonrpc/go-server/assembly/linux/release.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh b/examples/general/jsonrpc/go-server/assembly/linux/test.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh
rename to examples/general/jsonrpc/go-server/assembly/linux/test.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh b/examples/general/jsonrpc/go-server/assembly/mac/dev.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh
rename to examples/general/jsonrpc/go-server/assembly/mac/dev.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh b/examples/general/jsonrpc/go-server/assembly/mac/release.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh
rename to examples/general/jsonrpc/go-server/assembly/mac/release.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh b/examples/general/jsonrpc/go-server/assembly/mac/test.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh
rename to examples/general/jsonrpc/go-server/assembly/mac/test.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh b/examples/general/jsonrpc/go-server/assembly/windows/dev.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh
rename to examples/general/jsonrpc/go-server/assembly/windows/dev.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh b/examples/general/jsonrpc/go-server/assembly/windows/release.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh
rename to examples/general/jsonrpc/go-server/assembly/windows/release.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh b/examples/general/jsonrpc/go-server/assembly/windows/test.sh
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh
rename to examples/general/jsonrpc/go-server/assembly/windows/test.sh
diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml b/examples/general/jsonrpc/go-server/profiles/dev/log.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml
rename to examples/general/jsonrpc/go-server/profiles/dev/log.yml
diff --git a/examples/general/jsonrpc/go-server/profiles/dev/server.yml b/examples/general/jsonrpc/go-server/profiles/dev/server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4d74d2ef6fed9b0206729717d7b7081a3eadec96
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/profiles/dev/server.yml
@@ -0,0 +1,75 @@
+# dubbo server yaml configure file
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name : "BDTService"
+  module : "dubbogo user-info server"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "dev"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+
+services:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "jsonrpc"
+    # 相当于dubbo.xml中的interface
+    interface : "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    version: "2.0"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    version: "2.0"
+    group: "as"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+
+protocols:
+  #-   name: "dubbo"
+  #    ip : "127.0.0.1"
+  #    port : 20000
+  "jsonrpc1":
+    name: "jsonrpc"
+    ip: "127.0.0.1"
+    port: 20001
+
diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/release/log.yml b/examples/general/jsonrpc/go-server/profiles/release/log.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/profiles/release/log.yml
rename to examples/general/jsonrpc/go-server/profiles/release/log.yml
diff --git a/examples/general/jsonrpc/go-server/profiles/release/server.yml b/examples/general/jsonrpc/go-server/profiles/release/server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3f7d2fdfff208801a6b89e7a90350e57133f31c3
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/profiles/release/server.yml
@@ -0,0 +1,75 @@
+# dubbo server yaml configure file
+
+# application config
+application_config:
+    organization : "ikurento.com"
+    name : "BDTService"
+    module : "dubbogo user-info server"
+    version : "0.0.1"
+    owner : "ZX"
+    environment : "release"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+
+services:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "jsonrpc"
+   # 相当于dubbo.xml中的interface
+    interface : "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+      - name: "GetUser"
+        retries: 1
+        loadbalance: "random"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    version: "2.0"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    version: "2.0"
+    group: "as"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+
+protocols:
+  #-   name: "dubbo"
+  #    ip : "127.0.0.1"
+  #    port : 20000
+  "jsonrpc1":
+      name: "jsonrpc"
+      ip: "127.0.0.1"
+      port: 20001
+
diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/test/log.yml b/examples/general/jsonrpc/go-server/profiles/test/log.yml
similarity index 100%
rename from examples/jsonrpc/with-configcenter-go-server/profiles/test/log.yml
rename to examples/general/jsonrpc/go-server/profiles/test/log.yml
diff --git a/examples/general/jsonrpc/go-server/profiles/test/server.yml b/examples/general/jsonrpc/go-server/profiles/test/server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..dd0637e7970281236b92e37888c554d83d87de96
--- /dev/null
+++ b/examples/general/jsonrpc/go-server/profiles/test/server.yml
@@ -0,0 +1,75 @@
+# dubbo server yaml configure file
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name : "BDTService"
+  module : "dubbogo user-info server"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "test"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+
+services:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "hangzhouzk"
+    protocol : "jsonrpc"
+    # 相当于dubbo.xml中的interface
+    interface : "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider1":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    version: "2.0"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+  "UserProvider2":
+    registry: "hangzhouzk"
+    protocol: "jsonrpc"
+    interface: "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    version: "2.0"
+    group: "as"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+
+protocols:
+  #-   name: "dubbo"
+  #    ip : "127.0.0.1"
+  #    port : 20000
+  "jsonrpc1":
+    name: "jsonrpc"
+    ip: "127.0.0.1"
+    port: 20001
+
diff --git a/examples/jsonrpc/java-client/build.sh b/examples/general/jsonrpc/java-client/build.sh
similarity index 100%
rename from examples/jsonrpc/java-client/build.sh
rename to examples/general/jsonrpc/java-client/build.sh
diff --git a/examples/jsonrpc/java-client/pom.xml b/examples/general/jsonrpc/java-client/pom.xml
similarity index 100%
rename from examples/jsonrpc/java-client/pom.xml
rename to examples/general/jsonrpc/java-client/pom.xml
diff --git a/examples/jsonrpc/java-client/src/main/assembly/assembly.xml b/examples/general/jsonrpc/java-client/src/main/assembly/assembly.xml
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/assembly/assembly.xml
rename to examples/general/jsonrpc/java-client/src/main/assembly/assembly.xml
diff --git a/examples/jsonrpc/java-client/src/main/assembly/conf/dubbo.properties b/examples/general/jsonrpc/java-client/src/main/assembly/conf/dubbo.properties
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/assembly/conf/dubbo.properties
rename to examples/general/jsonrpc/java-client/src/main/assembly/conf/dubbo.properties
diff --git a/examples/jsonrpc/java-client/src/main/assembly/conf/log4j.properties b/examples/general/jsonrpc/java-client/src/main/assembly/conf/log4j.properties
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/assembly/conf/log4j.properties
rename to examples/general/jsonrpc/java-client/src/main/assembly/conf/log4j.properties
diff --git a/examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a38dbfba906a951fcf8bd481650608bd5d35c9f
--- /dev/null
+++ b/examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
@@ -0,0 +1,196 @@
+// *****************************************************
+// DESC    : dubbo consumer
+// AUTHOR  : writtey by 包增辉(https://github.com/baozh)
+// VERSION : 1.0
+// LICENCE : Apache License 2.0
+// EMAIL   : alexstocks@foxmail.com
+// MOD     : 2016-10-19 17:03
+// FILE    : Consumer.java
+// ******************************************************
+
+package com.ikurento.user;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import com.alibaba.dubbo.rpc.service.EchoService;
+import java.util.List;
+
+public class Consumer {
+    // Define a private variable (Required in Spring)
+    private UserProvider userProvider;
+    private UserProvider userProvider1;
+    private UserProvider userProvider2;
+
+    // Spring DI (Required in Spring)
+    public void setUserProvider(UserProvider u) {
+        this.userProvider = u;
+    }
+    public void setUserProvider1(UserProvider u) {
+        this.userProvider1 = u;
+    }
+    public void setUserProvider2(UserProvider u) {
+        this.userProvider2 = u;
+    }
+
+    // Start the entry function for consumer (Specified in the configuration file)
+    public void start() throws Exception {
+        System.out.println("\n\ntest");
+        testGetUser();
+        testGetUsers();
+        System.out.println("\n\ntest1");
+        testGetUser1();
+        testGetUsers1();
+        System.out.println("\n\ntest2");
+        testGetUser2();
+        testGetUsers2();
+        Thread.sleep(2000);
+    }
+
+    private void testGetUser() throws Exception {
+        try {
+            EchoService echoService = (EchoService)userProvider;
+            Object status = echoService.$echo("OK");
+            System.out.println("echo: "+status);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            User user1 = userProvider.GetUser("A003");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
+                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
+            User user2 = userProvider.GetUser0("A003","Moorse");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
+                    + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                    + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
+
+            userProvider.GetUser3();
+            System.out.println("GetUser3 succ");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUsers() throws Exception {
+        try {
+            List<String> userIDList = new ArrayList<String>();
+            userIDList.add("A001");
+            userIDList.add("A002");
+            userIDList.add("A003");
+
+            List<User> userList = userProvider.GetUsers(userIDList);
+
+            for (int i = 0; i < userList.size(); i++) {
+                User user = userList.get(i);
+                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
+                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUser1() throws Exception {
+        try {
+            EchoService echoService = (EchoService)userProvider1;
+            Object status = echoService.$echo("OK");
+            System.out.println("echo: "+status);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            User user1 = userProvider1.GetUser("A003");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
+                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
+            User user2 = userProvider1.GetUser0("A003","Moorse");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
+                    + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider1.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                    + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
+
+            userProvider1.GetUser3();
+            System.out.println("GetUser3 succ");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUsers1() throws Exception {
+        try {
+            List<String> userIDList = new ArrayList<String>();
+            userIDList.add("A001");
+            userIDList.add("A002");
+            userIDList.add("A003");
+
+            List<User> userList = userProvider1.GetUsers(userIDList);
+
+            for (int i = 0; i < userList.size(); i++) {
+                User user = userList.get(i);
+                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
+                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUser2() throws Exception {
+        try {
+            EchoService echoService = (EchoService)userProvider2;
+            Object status = echoService.$echo("OK");
+            System.out.println("echo: "+status);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            User user1 = userProvider2.GetUser("A003");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
+                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
+            User user2 = userProvider2.GetUser0("A003","Moorse");
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
+                    + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider2.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                    " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                    + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
+
+            userProvider2.GetUser3();
+            System.out.println("GetUser3 succ");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void testGetUsers2() throws Exception {
+        try {
+            List<String> userIDList = new ArrayList<String>();
+            userIDList.add("A001");
+            userIDList.add("A002");
+            userIDList.add("A003");
+
+            List<User> userList = userProvider2.GetUsers(userIDList);
+
+            for (int i = 0; i < userList.size(); i++) {
+                User user = userList.get(i);
+                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
+                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Gender.java b/examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/Gender.java
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Gender.java
rename to examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/Gender.java
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/User.java b/examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/User.java
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/java/com/ikurento/user/User.java
rename to examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/User.java
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java b/examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java
rename to examples/general/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java
diff --git a/examples/jsonrpc/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml b/examples/general/jsonrpc/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
similarity index 87%
rename from examples/jsonrpc/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
rename to examples/general/jsonrpc/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
index c01f4ab064a83aa62adc7de676cdaede7108bd23..da21e8a359c003983ebea3269d4f2dfd255e3b29 100644
--- a/examples/jsonrpc/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
+++ b/examples/general/jsonrpc/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
@@ -37,5 +37,9 @@
 	<!-- dubbo:reference id="userProvider" protocol="dubbo" interface="com.ikurento.user.UserProvider">
             <dubbo:parameter key="heartbeat" value="10000"/ -->
     </dubbo:reference>
+	<dubbo:reference id="userProvider1" protocol="jsonrpc" version="2.0" interface="com.ikurento.user.UserProvider">
+	</dubbo:reference>
+	<dubbo:reference id="userProvider2" protocol="jsonrpc" version="2.0" group="as" interface="com.ikurento.user.UserProvider">
+	</dubbo:reference>
 
 </beans>
diff --git a/examples/dubbo/java-client/src/main/resources/META-INF/spring/service.xml b/examples/general/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml
similarity index 90%
rename from examples/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
rename to examples/general/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml
index 625a879f97f5a21498be1efc1aa97fce68e76c61..db9fc3cba5a359b8835af53b81e50f8296d2e489 100644
--- a/examples/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
+++ b/examples/general/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml
@@ -24,6 +24,8 @@
 	<bean class="com.ikurento.user.Consumer" init-method="start">
 		<!-- 声明这个类 要使用的服务名-->
 		<property name="userProvider" ref="userProvider" />
+		<property name="userProvider1" ref="userProvider1" />
+		<property name="userProvider2" ref="userProvider2" />
 	</bean>
 
 	<!-- App config -->
diff --git a/examples/jsonrpc/java-client/src/main/resources/log4j.properties b/examples/general/jsonrpc/java-client/src/main/resources/log4j.properties
similarity index 100%
rename from examples/jsonrpc/java-client/src/main/resources/log4j.properties
rename to examples/general/jsonrpc/java-client/src/main/resources/log4j.properties
diff --git a/examples/jsonrpc/java-server/build.sh b/examples/general/jsonrpc/java-server/build.sh
similarity index 100%
rename from examples/jsonrpc/java-server/build.sh
rename to examples/general/jsonrpc/java-server/build.sh
diff --git a/examples/jsonrpc/java-server/pom.xml b/examples/general/jsonrpc/java-server/pom.xml
similarity index 100%
rename from examples/jsonrpc/java-server/pom.xml
rename to examples/general/jsonrpc/java-server/pom.xml
diff --git a/examples/jsonrpc/java-server/script/debug.sh b/examples/general/jsonrpc/java-server/script/debug.sh
similarity index 100%
rename from examples/jsonrpc/java-server/script/debug.sh
rename to examples/general/jsonrpc/java-server/script/debug.sh
diff --git a/examples/jsonrpc/java-server/src/main/assembly/assembly.xml b/examples/general/jsonrpc/java-server/src/main/assembly/assembly.xml
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/assembly/assembly.xml
rename to examples/general/jsonrpc/java-server/src/main/assembly/assembly.xml
diff --git a/examples/jsonrpc/java-server/src/main/assembly/conf/dubbo.properties b/examples/general/jsonrpc/java-server/src/main/assembly/conf/dubbo.properties
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/assembly/conf/dubbo.properties
rename to examples/general/jsonrpc/java-server/src/main/assembly/conf/dubbo.properties
diff --git a/examples/jsonrpc/java-server/src/main/assembly/conf/log4j.properties b/examples/general/jsonrpc/java-server/src/main/assembly/conf/log4j.properties
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/assembly/conf/log4j.properties
rename to examples/general/jsonrpc/java-server/src/main/assembly/conf/log4j.properties
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/Gender.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/Gender.java
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/Gender.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/Gender.java
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/Provider.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/Provider.java
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/Provider.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/Provider.java
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/Response.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/Response.java
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/Response.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/Response.java
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/User.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/User.java
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/User.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/User.java
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProvider.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProvider.java
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProvider.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProvider.java
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
similarity index 94%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
index 753a6f89a5f60e0f4884711d4c3b79e52ed2f094..9e22b78b3de2412c8aefbfdbb37d2886d016a0f4 100644
--- a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
+++ b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
@@ -9,8 +9,8 @@ import org.slf4j.LoggerFactory;
 import java.util.*;
 
 public class UserProviderAnotherImpl implements UserProvider {
-    // private static final Logger logger = LoggerFactory.getLogger(getClass()); // 只输出到dubbo的log(logs/server.log)
-    private static final Logger logger = LoggerFactory.getLogger("userLogger"); // 输出到user-server.log
+    // private static final Logger logger = LoggerFactory.getLogger(getClass()); // Only output to dubbo's log(logs/server.log)
+    private static final Logger logger = LoggerFactory.getLogger("userLogger"); // Output to user-server.log
 
     private Map<String, User> userMap = new HashMap<String, User>();
 
diff --git a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
similarity index 93%
rename from examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
rename to examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
index 960c678cf76cf4bafb3de9d5ce2a587b61aa1bac..1ff8afa62220463932872df2172b35e4e16a4591 100644
--- a/examples/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
+++ b/examples/general/jsonrpc/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
@@ -14,8 +14,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class UserProviderImpl implements UserProvider {
-    // private static final Logger logger = LoggerFactory.getLogger(getClass()); // 只输出到dubbo的log(logs/server.log)
-    private static final Logger LOG = LoggerFactory.getLogger("UserLogger"); // 输出到user-server.log
+    // private static final Logger logger = LoggerFactory.getLogger(getClass()); // Only output to dubbo's log(logs/server.log)
+    private static final Logger LOG = LoggerFactory.getLogger("UserLogger"); // Output to user-server.log
     Map<String, User> userMap = new HashMap<String, User>();
 
     public UserProviderImpl() {
diff --git a/examples/jsonrpc/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml b/examples/general/jsonrpc/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
rename to examples/general/jsonrpc/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
diff --git a/examples/jsonrpc/java-server/src/main/resources/log4j.properties b/examples/general/jsonrpc/java-server/src/main/resources/log4j.properties
similarity index 100%
rename from examples/jsonrpc/java-server/src/main/resources/log4j.properties
rename to examples/general/jsonrpc/java-server/src/main/resources/log4j.properties
diff --git a/examples/generic/go-client/app/client.go b/examples/generic/go-client/app/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d5a1bc5fa6cb186fcf456d385f8dad16b750ea3
--- /dev/null
+++ b/examples/generic/go-client/app/client.go
@@ -0,0 +1,100 @@
+/*
+ * 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 main
+
+import (
+	"fmt"
+	"time"
+)
+
+import (
+	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/protocol/dubbo"
+	_ "github.com/apache/dubbo-go/registry/protocol"
+
+	_ "github.com/apache/dubbo-go/filter/impl"
+
+	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
+	_ "github.com/apache/dubbo-go/cluster/loadbalance"
+	_ "github.com/apache/dubbo-go/registry/zookeeper"
+)
+
+var (
+	survivalTimeout int = 10e9
+)
+
+// they are necessary:
+// 		export CONF_CONSUMER_FILE_PATH="xxx"
+// 		export APP_LOG_CONF_FILE="xxx"
+func main() {
+	println("\n\ntest")
+	test()
+	println("\n\ntest2")
+	test2()
+
+}
+func test() {
+	var appName = "UserProviderGer"
+	var referenceConfig = config.ReferenceConfig{
+		InterfaceName: "com.ikurento.user.UserProvider",
+		Cluster:       "failover",
+		Registry:      "hangzhouzk",
+		Protocol:      dubbo.DUBBO,
+		Generic:       true,
+	}
+	referenceConfig.GenericLoad(appName) //appName is the unique identification of RPCService
+
+	time.Sleep(3 * time.Second)
+	println("\n\n\nstart to generic invoke")
+	resp, err := referenceConfig.GetRPCService().(*config.GenericService).Invoke([]interface{}{"GetUser", []string{"java.lang.String"}, []interface{}{"A003"}})
+	if err != nil {
+		panic(err)
+	}
+	fmt.Printf("res: %+v\n", resp)
+	println("succ!")
+
+}
+func test2() {
+	var appName = "UserProviderGer"
+	var referenceConfig = config.ReferenceConfig{
+		InterfaceName: "com.ikurento.user.UserProvider",
+		Cluster:       "failover",
+		Registry:      "hangzhouzk",
+		Protocol:      dubbo.DUBBO,
+		Generic:       true,
+	}
+	referenceConfig.GenericLoad(appName) //appName is the unique identification of RPCService
+
+	time.Sleep(3 * time.Second)
+	println("\n\n\nstart to generic invoke")
+	user := User{
+		Id:   "3213",
+		Name: "panty",
+		Age:  25,
+		Time: time.Now(),
+		Sex:  Gender(MAN),
+	}
+	resp, err := referenceConfig.GetRPCService().(*config.GenericService).Invoke([]interface{}{"queryUser", []string{"com.ikurento.user.User"}, []interface{}{user}})
+	if err != nil {
+		panic(err)
+	}
+	fmt.Printf("res: %+v\n", resp)
+	println("succ!")
+
+}
diff --git a/examples/generic/go-client/app/user.go b/examples/generic/go-client/app/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..9b226e24456e850f1b31fc0501e04d573cec35fd
--- /dev/null
+++ b/examples/generic/go-client/app/user.go
@@ -0,0 +1,57 @@
+package main
+
+import (
+	"strconv"
+	"time"
+)
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+type Gender hessian.JavaEnum
+
+const (
+	MAN hessian.JavaEnum = iota
+	WOMAN
+)
+
+var genderName = map[hessian.JavaEnum]string{
+	MAN:   "MAN",
+	WOMAN: "WOMAN",
+}
+
+var genderValue = map[string]hessian.JavaEnum{
+	"MAN":   MAN,
+	"WOMAN": WOMAN,
+}
+
+func (g Gender) JavaClassName() string {
+	return "com.ikurento.user.Gender"
+}
+
+func (g Gender) String() string {
+	s, ok := genderName[hessian.JavaEnum(g)]
+	if ok {
+		return s
+	}
+
+	return strconv.Itoa(int(g))
+}
+
+func (g Gender) EnumValue(s string) hessian.JavaEnum {
+	v, ok := genderValue[s]
+	if ok {
+		return v
+	}
+
+	return hessian.InvalidJavaEnum
+}
+
+type User struct {
+	// !!! Cannot define lowercase names of variable
+	Id   string
+	Name string
+	Age  int32
+	Time time.Time
+	Sex  Gender // 注意此处,java enum Object <--> go string
+}
diff --git a/examples/generic/go-client/assembly/bin/load.sh b/examples/generic/go-client/assembly/bin/load.sh
new file mode 100644
index 0000000000000000000000000000000000000000..07d5d15eac7b7974845e36c3807e7ec55875de65
--- /dev/null
+++ b/examples/generic/go-client/assembly/bin/load.sh
@@ -0,0 +1,196 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : dubbogo app devops script
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-05-13 02:01
+# FILE    : load.sh
+# ******************************************************
+
+APP_NAME="APPLICATION_NAME"
+APP_ARGS=""
+SLEEP_INTERVAL=5
+MAX_LIFETIME=4000
+
+PROJECT_HOME=""
+OS_NAME=`uname`
+if [[ ${OS_NAME} != "Windows" ]]; then
+    PROJECT_HOME=`pwd`
+    PROJECT_HOME=${PROJECT_HOME}"/"
+else
+    APP_NAME="APPLICATION_NAME.exe"
+fi
+
+export CONF_CONSUMER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE"
+export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
+# export GOTRACEBACK=system
+# export GODEBUG=gctrace=1
+
+usage() {
+    echo "Usage: $0 start [conf suffix]"
+    echo "       $0 stop"
+    echo "       $0 term"
+    echo "       $0 restart"
+    echo "       $0 list"
+    echo "       $0 monitor"
+    echo "       $0 crontab"
+    exit
+}
+
+start() {
+    arg=$1
+    if [ "$arg" = "" ];then
+        echo "No registry type! Default client.yml!"
+    else
+        export CONF_CONSUMER_FILE_PATH=${CONF_CONSUMER_FILE_PATH//\.yml/\_$arg\.yml}
+    fi
+    if [ ! -f "${CONF_CONSUMER_FILE_PATH}" ];then
+        echo $CONF_CONSUMER_FILE_PATH" is not existing!"
+        return
+    fi
+    APP_LOG_PATH=${PROJECT_HOME}"logs/"
+    mkdir -p ${APP_LOG_PATH}
+    APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
+    chmod u+x ${APP_BIN}
+    # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
+    CMD="${APP_BIN}"
+    eval ${CMD}
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    CUR=`date +%FT%T`
+    if [ "${PID}" != "" ]; then
+        for p in ${PID}
+        do
+            echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
+        done
+    fi
+}
+
+stop() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    if [ "${PID}" != "" ];
+    then
+        for ps in ${PID}
+        do
+            echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
+            kill -2 ${ps}
+        done
+    fi
+}
+
+
+term() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    if [ "${PID}" != "" ];
+    then
+        for ps in ${PID}
+        do
+            echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
+            kill -9 ${ps}
+        done
+    fi
+}
+
+list() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
+    fi
+
+    if [ "${PID}" != "" ]; then
+        echo "list ${APP_NAME}"
+
+        if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
+            echo "index: user, pid, start, duration"
+        else
+            echo "index: PID, WINPID, UID, STIME, COMMAND"
+        fi
+        idx=0
+        for ps in ${PID}
+        do
+            echo "${idx}: ${ps}"
+            ((idx ++))
+        done
+    fi
+}
+
+monitor() {
+    idx=0
+    while true; do
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+        if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+            PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+        fi
+        if [[ "${PID}" == "" ]]; then
+            start
+            idx=0
+        fi
+
+        ((LIFE=idx*${SLEEP_INTERVAL}))
+        echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
+        ((idx ++))
+        sleep ${SLEEP_INTERVAL}
+    done
+}
+
+crontab() {
+    idx=0
+    while true; do
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+        if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+            PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+        fi
+        if [[ "${PID}" == "" ]]; then
+            start
+            idx=0
+        fi
+
+        ((LIFE=idx*${SLEEP_INTERVAL}))
+        echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
+        ((idx ++))
+        sleep ${SLEEP_INTERVAL}
+        if [[ ${LIFE} -gt ${MAX_LIFETIME} ]]; then
+            kill -9 ${PID}
+        fi
+    done
+}
+
+opt=$1
+case C"$opt" in
+    Cstart)
+        start $2
+        ;;
+    Cstop)
+        stop
+        ;;
+    Cterm)
+        term
+        ;;
+    Crestart)
+        term
+        start $2
+        ;;
+    Clist)
+        list
+        ;;
+    Cmonitor)
+        monitor
+        ;;
+    Ccrontab)
+        crontab
+        ;;
+    C*)
+        usage
+        ;;
+esac
+
diff --git a/examples/generic/go-client/assembly/common/app.properties b/examples/generic/go-client/assembly/common/app.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6bbd6db850ceeaf5ff873fee01a3578237cbd557
--- /dev/null
+++ b/examples/generic/go-client/assembly/common/app.properties
@@ -0,0 +1,17 @@
+# dubbogo application configure script
+# ******************************************************
+# DESC    : dubbogo environment variable
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:29
+# FILE    : app.properties
+# ******************************************************
+
+export TARGET_EXEC_NAME="user_info_client"
+# BUILD_PACKAGE="dubbogo-examples/user-info/client/app"
+export BUILD_PACKAGE="app"
+
+export TARGET_CONF_FILE="conf/client.yml"
+export TARGET_LOG_CONF_FILE="conf/log.yml"
diff --git a/examples/generic/go-client/assembly/common/build.sh b/examples/generic/go-client/assembly/common/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..e72418297ad2f0ac6985476b5a8d5e03b9e7584e
--- /dev/null
+++ b/examples/generic/go-client/assembly/common/build.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:28
+# FILE    : build.sh
+# ******************************************************
+
+rm -rf target/
+
+PROJECT_HOME=`pwd`
+TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
+
+TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
+version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
+if [[ ${GOOS} == "windows" ]]; then
+    TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
+fi
+TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
+if [[ $PROFILE == "dev" ||  $PROFILE == "test" ]]; then
+    # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
+    # GFLAGS=-gcflags "-N -l" -race -v
+    # GFLAGS="-gcflags \"-N -l\" -v"
+    cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
+else
+    # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
+    # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
+    # -w基本没啥损失。-s的损失就有点大了。
+    cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
+fi
+
+TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
+
+mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
+
+SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
+BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
+CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
+
+mkdir -p ${SBIN_DIR}
+mkdir -p ${CONF_DIR}
+
+mv ${TARGET_NAME} ${SBIN_DIR}
+cp -r assembly/bin ${BIN_DIR}
+cd ${BIN_DIR}/bin/ && mv load.sh load_${TARGET_EXEC_NAME}.sh && cd -
+
+platform=$(uname)
+# modify APPLICATION_NAME
+if [ ${platform} == "Darwin" ]; then
+    sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
+fi
+
+# modify TARGET_CONF_FILE
+if [ ${platform} == "Darwin" ]; then
+    sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
+fi
+
+# modify TARGET_LOG_CONF_FILE
+if [ ${platform} == "Darwin" ]; then
+    sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
+fi
+
+cp -r profiles/${PROFILE}/* ${CONF_DIR}
+
+cd ${TARGET_FOLDER}
+
+tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
+
diff --git a/examples/generic/go-client/assembly/linux/dev.sh b/examples/generic/go-client/assembly/linux/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..3373f01b948b708cd7bc1958c9d56a9042c60a68
--- /dev/null
+++ b/examples/generic/go-client/assembly/linux/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-18 13:24
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="dev"
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/linux/release.sh b/examples/generic/go-client/assembly/linux/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..34867b8b3488778cd76a1dc7802393dcab6b0df0
--- /dev/null
+++ b/examples/generic/go-client/assembly/linux/release.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="release"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/linux/test.sh b/examples/generic/go-client/assembly/linux/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1bbbefd1e14e08c16deaf859e2841f4d1fe88e9c
--- /dev/null
+++ b/examples/generic/go-client/assembly/linux/test.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="test"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/mac/dev.sh b/examples/generic/go-client/assembly/mac/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b68ac83b6524a6713cd90c4fc5968fe64b1a9545
--- /dev/null
+++ b/examples/generic/go-client/assembly/mac/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-18 13:24
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+export PROFILE="dev"
+
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+	. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+	sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/mac/release.sh b/examples/generic/go-client/assembly/mac/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..688288b3b1b989e8af70a3674b34ea8e0668f3b4
--- /dev/null
+++ b/examples/generic/go-client/assembly/mac/release.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+export PROFILE="release"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/mac/test.sh b/examples/generic/go-client/assembly/mac/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..56d6c11ecd6a1dc5984c74b88c10be9239e57428
--- /dev/null
+++ b/examples/generic/go-client/assembly/mac/test.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+export PROFILE="test"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/windows/dev.sh b/examples/generic/go-client/assembly/windows/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..91cf6f23bcbecb26db798469a30529261aabbbb6
--- /dev/null
+++ b/examples/generic/go-client/assembly/windows/dev.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-18 13:24
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="dev"
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/windows/release.sh b/examples/generic/go-client/assembly/windows/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f317720bd53d9c9e5f8f484b6eb682c9c736af0c
--- /dev/null
+++ b/examples/generic/go-client/assembly/windows/release.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+export PROFILE="release"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/assembly/windows/test.sh b/examples/generic/go-client/assembly/windows/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7dd2bec5260e647b57a46aaa37acc098babff068
--- /dev/null
+++ b/examples/generic/go-client/assembly/windows/test.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+export PROFILE="test"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/generic/go-client/profiles/dev/client.yml b/examples/generic/go-client/profiles/dev/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f4e3180aa88cbbdffd519d70b3cc83b2e2b6674a
--- /dev/null
+++ b/examples/generic/go-client/profiles/dev/client.yml
@@ -0,0 +1,55 @@
+# dubbo client yaml configure file
+
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo genric client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "dev"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+
+protocol_conf:
+  dubbo:
+    reconnect_interval: 0
+    connection_number: 2
+    heartbeat_period: "5s"
+    session_timeout: "20s"
+    pool_size: 64
+    pool_ttl: 600
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 10240
+      session_name: "client"
diff --git a/examples/generic/go-client/profiles/dev/log.yml b/examples/generic/go-client/profiles/dev/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..59fa4279ad85272c4c49d532beaf23b74d00f58a
--- /dev/null
+++ b/examples/generic/go-client/profiles/dev/log.yml
@@ -0,0 +1,28 @@
+
+level: "debug"
+development: true
+disableCaller: false
+disableStacktrace: false
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/generic/go-client/profiles/release/client.yml b/examples/generic/go-client/profiles/release/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5a21bca6c93336a8888b55a6a7e81f9240c709a5
--- /dev/null
+++ b/examples/generic/go-client/profiles/release/client.yml
@@ -0,0 +1,55 @@
+# dubbo client yaml configure file
+
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo generic client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "release"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+
+protocol_conf:
+  dubbo:
+    reconnect_interval: 0
+    connection_number: 2
+    heartbeat_period: "5s"
+    session_timeout: "20s"
+    pool_size: 64
+    pool_ttl: 600
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 10240
+      session_name: "client"
diff --git a/examples/generic/go-client/profiles/release/log.yml b/examples/generic/go-client/profiles/release/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e0514be020eedf594d99d112183cdd5ce199e46d
--- /dev/null
+++ b/examples/generic/go-client/profiles/release/log.yml
@@ -0,0 +1,28 @@
+
+level: "warn"
+development: true
+disableCaller: true
+disableStacktrace: true
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/generic/go-client/profiles/test/client.yml b/examples/generic/go-client/profiles/test/client.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7442c64c71abf47db9c15d85c6bcd2ced8057e46
--- /dev/null
+++ b/examples/generic/go-client/profiles/test/client.yml
@@ -0,0 +1,55 @@
+# dubbo client yaml configure file
+
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name  : "BDTService"
+  module : "dubbogo user-info client"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "test"
+
+registries :
+  "hangzhouzk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+    username: ""
+    password: ""
+  "shanghaizk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2182"
+    username: ""
+    password: ""
+
+references:
+
+protocol_conf:
+  dubbo:
+    reconnect_interval: 0
+    connection_number: 2
+    heartbeat_period: "5s"
+    session_timeout: "20s"
+    pool_size: 64
+    pool_ttl: 600
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 10240
+      session_name: "client"
diff --git a/examples/generic/go-client/profiles/test/log.yml b/examples/generic/go-client/profiles/test/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..baee0b7248484e425f88f35ab128212c931ff85e
--- /dev/null
+++ b/examples/generic/go-client/profiles/test/log.yml
@@ -0,0 +1,28 @@
+
+level: "info"
+development: false
+disableCaller: false
+disableStacktrace: true
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/generic/java-server/build.sh b/examples/generic/java-server/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..0c197da639c1c1d9375e18c24dd73366c49deefe
--- /dev/null
+++ b/examples/generic/java-server/build.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# ******************************************************
+# EMAIL   : alexstocks@foxmail.com
+# FILE    : build.sh
+# ******************************************************
+
+# mvn dependency:sources
+mvn clean package -Dmaven.test.skip
+# mvn -X clean compile package -DskipTests=true
diff --git a/examples/generic/java-server/pom.xml b/examples/generic/java-server/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..975157865e59f24693d755dd20b0aac4b179a793
--- /dev/null
+++ b/examples/generic/java-server/pom.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.ikurento</groupId>
+    <artifactId>user-info-server</artifactId>
+    <packaging>jar</packaging>
+    <version>0.2.0</version>
+    <description>The demo provider module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+
+        <dubbo-version>2.6.5</dubbo-version>
+        <dubbo-jsonrpc-version>1.0.1</dubbo-jsonrpc-version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>dubbo-dependencies-bom</artifactId>
+                <version>${dubbo-version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.7.25</version>
+		</dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${dubbo-version}</version>
+            <exclusions>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-framework</artifactId>
+            <version>2.12.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.qianmi</groupId>
+            <artifactId>dubbo-rpc-jsonrpc</artifactId>
+            <version>${dubbo-jsonrpc-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty</artifactId>
+            <version>6.1.26</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.9.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.9.9</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.sgroschupf</groupId>
+            <artifactId>zkclient</artifactId>
+            <version>0.1</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>org.apache.zookeeper</artifactId>
+                    <groupId>zookeeper</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>3.4.14</version>
+        </dependency>
+
+    </dependencies>
+
+    <repositories>
+		<repository>
+            <id>nexus-aliyu</id>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+		<releases>
+			<enabled>true</enabled>
+		</releases>
+		<snapshots>
+			<enabled>false</enabled>
+		</snapshots>
+		</repository>
+    </repositories>
+    <pluginRepositories>
+		  <pluginRepository>
+              <id>nexus-aliyu</id>
+              <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+			<releases>
+			<enabled>true</enabled>
+			</releases>
+			<snapshots>
+			<enabled>false</enabled>
+			</snapshots>
+		  </pluginRepository>
+		</pluginRepositories>
+
+
+    <build>
+
+        <plugins>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>unpack</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>com.alibaba</groupId>
+                                    <artifactId>dubbo</artifactId>
+                                    <version>${dubbo-version}</version>
+                                    <outputDirectory>${project.build.directory}/dubbo</outputDirectory>
+                                    <includes>META-INF/assembly/**</includes>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
+
+
diff --git a/examples/generic/java-server/script/debug.sh b/examples/generic/java-server/script/debug.sh
new file mode 100644
index 0000000000000000000000000000000000000000..27c5d800d846018127e762944151aa8e9ad4495d
--- /dev/null
+++ b/examples/generic/java-server/script/debug.sh
@@ -0,0 +1,16 @@
+#!/us1r/bin/env bash
+# ******************************************************
+# DESC    :
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-09 21:52
+# FILE    : to debug user info dubbo server
+# ******************************************************
+
+# jdb -classpath /Users/alex/tmp/us/conf:/Users/alex/tmp/us/lib/*:/Users/alex/test/java/dubbo/2.5.4/dubbo-remoting/dubbo-remoting-api/src/main/java/ com.alibaba.dubbo.container.Main
+jdb -classpath /Users/alex/tmp/us/conf:/Users/alex/tmp/us/lib/* -sourcepath /Users/alex/test/java/dubbo/2.5.4/dubbo-remoting/dubbo-remoting-api/src/main/java/:/Users/alex/tmp/java-server/src/main/java com.alibaba.dubbo.container.Main
+# jdb stop at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec:76
+# run
+
diff --git a/examples/generic/java-server/src/main/assembly/assembly.xml b/examples/generic/java-server/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f01fea20f5391112cccb88c87bfe4ae1b59750a
--- /dev/null
+++ b/examples/generic/java-server/src/main/assembly/assembly.xml
@@ -0,0 +1,45 @@
+<!--
+ - Copyright 1999-2011 Alibaba Group.
+ -  
+ - Licensed 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.
+-->
+<assembly>
+	<id>assembly</id>
+	<formats>
+		<format>tar.gz</format>
+	</formats>
+	<includeBaseDirectory>true</includeBaseDirectory>
+	<fileSets>
+		<fileSet>
+			<directory>${project.build.directory}/dubbo/META-INF/assembly/bin</directory>
+			<outputDirectory>bin</outputDirectory>
+			<fileMode>0755</fileMode>
+            <directoryMode>0755</directoryMode>
+		</fileSet>
+		<fileSet>
+            <directory>src/main/assembly/conf</directory>
+            <includes>
+                <include>dubbo.properties</include>
+                <include>log4j.*</include>
+            </includes>
+			<outputDirectory>conf</outputDirectory>
+			<fileMode>0644</fileMode>
+            <directoryMode>0755</directoryMode>
+		</fileSet>
+	</fileSets>
+	<dependencySets>
+		<dependencySet>
+			<outputDirectory>lib</outputDirectory>
+		</dependencySet>
+	</dependencySets>
+</assembly>
\ No newline at end of file
diff --git a/examples/generic/java-server/src/main/assembly/conf/dubbo.properties b/examples/generic/java-server/src/main/assembly/conf/dubbo.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2826f31303717256725b02a79e1698043709d2f3
--- /dev/null
+++ b/examples/generic/java-server/src/main/assembly/conf/dubbo.properties
@@ -0,0 +1,14 @@
+### dubbo注册中心配置 ##
+dubbo.container = log4j,spring
+dubbo.application.name = user-info-server
+dubbo.application.environment = product
+dubbo.application.owner = AlexStocks
+dubbo.registry.address = 127.0.0.1:2181
+dubbo.registry.protocol = zookeeper
+dubbo.consumer.timeout = 10000
+dubbo.provider.timeout = 10000
+dubbo.protocol.name = dubbo
+dubbo.protocol.port = 10000
+
+dubbo.log4j.file = logs/dubbo.log
+dubbo.log4j.level = INFO
diff --git a/examples/generic/java-server/src/main/assembly/conf/log4j.properties b/examples/generic/java-server/src/main/assembly/conf/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..13c80493329261ea677de77624b363bf99c82652
--- /dev/null
+++ b/examples/generic/java-server/src/main/assembly/conf/log4j.properties
@@ -0,0 +1,20 @@
+## Logger configure file for myproject
+log.dir=logs/
+datestamp=yyyy-MM-dd/HH:mm:ss.SSS
+
+log4j.rootLogger=DEBUG, file, console
+
+log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.file.threshold=DEBUG
+log4j.appender.file.File=${log.dir}/log4j.log
+log4j.appender.file.DatePattern=-yyyyMMddHH
+log4j.appender.file.ImmediateFlush=true
+log4j.appender.file.Append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
diff --git a/examples/generic/java-server/src/main/java/com/ikurento/user/Gender.java b/examples/generic/java-server/src/main/java/com/ikurento/user/Gender.java
new file mode 100644
index 0000000000000000000000000000000000000000..72c30ae8d4bae8fc71b4cb598205141b2d1d2020
--- /dev/null
+++ b/examples/generic/java-server/src/main/java/com/ikurento/user/Gender.java
@@ -0,0 +1,6 @@
+package com.ikurento.user;
+
+public enum  Gender {
+    MAN,
+    WOMAN
+}
diff --git a/examples/generic/java-server/src/main/java/com/ikurento/user/Provider.java b/examples/generic/java-server/src/main/java/com/ikurento/user/Provider.java
new file mode 100644
index 0000000000000000000000000000000000000000..0031f5569fd5f16ded0da6e5426f78805fad4a42
--- /dev/null
+++ b/examples/generic/java-server/src/main/java/com/ikurento/user/Provider.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.ikurento.user;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Provider {
+
+    /**
+     * To get ipv6 address to work, add
+     * System.setProperty("java.net.preferIPv6Addresses", "true");
+     * before running your application.
+     */
+    public static void main(String[] args) throws Exception {
+        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.provider.xml"});
+        context.start();
+        System.in.read(); // press any key to exit
+    }
+}
diff --git a/examples/generic/java-server/src/main/java/com/ikurento/user/Response.java b/examples/generic/java-server/src/main/java/com/ikurento/user/Response.java
new file mode 100644
index 0000000000000000000000000000000000000000..3447e5c2537625f424b54291c53783a51922ae7b
--- /dev/null
+++ b/examples/generic/java-server/src/main/java/com/ikurento/user/Response.java
@@ -0,0 +1,76 @@
+package com.ikurento.user;
+
+import java.io.*;
+//import java.util.Objects;
+
+public final class Response<T> implements Serializable {
+    private static final long serialVersionUID = 3727205004706510648L;
+    public static final Integer OK = 200;
+    public static final Integer ERR = 500;
+    private Integer Status;
+    private String Err;
+    private T Data;
+
+    public Response() {
+    }
+
+    public static <T> Response<T> ok() {
+        Response r = new Response();
+        r.Status = OK;
+        return r;
+    }
+
+    public static <T> Response<T> ok(Object Data) {
+        Response r = new Response();
+        r.Status = OK;
+        r.Data = Data;
+        return r;
+    }
+
+    public static <T> Response<T> notOk(String Err) {
+        Response r = new Response();
+        r.Status = ERR;
+        r.Err = Err;
+        return r;
+    }
+
+    public static <T> Response<T> notOk(Integer Status, String Err) {
+        Response r = new Response();
+        r.Status = Status;
+        r.Err = Err;
+        return r;
+    }
+
+//    public Boolean isSuccess() {
+//        return Objects.equals(this.Status, OK);
+//    }
+
+    public Integer getStatus() {
+        return this.Status;
+    }
+
+    public void setStatus(Integer Status) {
+        this.Status = Status;
+    }
+
+    public String getErr() {
+        return this.Err;
+    }
+
+    public void setErr(String Err) {
+        this.Err = Err;
+    }
+
+    public T getData() {
+        return this.Data;
+    }
+
+    public void setData(T Data) {
+        this.Status = OK;
+        this.Data = Data;
+    }
+
+    public String toString() {
+        return "Response{Status=" + this.Status + ", Err='" + this.Err + '\'' + ", Data=" + this.Data + '}';
+    }
+}
\ No newline at end of file
diff --git a/examples/generic/java-server/src/main/java/com/ikurento/user/User.java b/examples/generic/java-server/src/main/java/com/ikurento/user/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..eafc0fe1c0e0c7b72a0fce73b6a333668797145e
--- /dev/null
+++ b/examples/generic/java-server/src/main/java/com/ikurento/user/User.java
@@ -0,0 +1,79 @@
+package com.ikurento.user;
+// ref: https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+import java.util.Date;
+import java.io.Serializable;
+
+public class User implements Serializable  {
+
+    private String id;
+
+    private String name;
+
+    private int age;
+
+    private Date time = new Date();
+
+    private Gender sex = Gender.MAN;
+
+    public User() {
+    }
+
+    public User(String id, String name, int age) {
+        this.id = id;
+        this.name = name;
+        this.age = age;
+    }
+
+    public User(String id, String name, int age, Date time, Gender sex) {
+        this.id = id;
+        this.name = name;
+        this.age = age;
+        this.time = time;
+        this.sex = sex;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public Date getTime() {
+        return time;
+    }
+
+    public void setTime(Date time) {
+        this.time = time;
+    }
+
+    public Gender getSex() {
+        return sex;
+    }
+
+    public void setSex(Gender sex) {
+        this.sex = sex;
+    }
+
+    public String toString() {
+        return "User{id:" + id + ", name:" + name + ", age:" + age + ", time:" + time + ", gender:" + sex + "}";
+    }
+}
diff --git a/examples/generic/java-server/src/main/java/com/ikurento/user/UserProvider.java b/examples/generic/java-server/src/main/java/com/ikurento/user/UserProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..24567d23be662312a4750f07b605c685a8dfa5fe
--- /dev/null
+++ b/examples/generic/java-server/src/main/java/com/ikurento/user/UserProvider.java
@@ -0,0 +1,32 @@
+package com.ikurento.user;
+// https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+import java.util.List;
+import java.util.Map;
+
+public interface UserProvider {
+
+    boolean isLimit(Gender gender, String name);
+
+    User GetUser(String userId); // the first alpha is Upper case to compatible with golang.
+
+    List<User> GetUsers(List<String> userIdList);
+
+    void GetUser3();
+
+    User GetUser0(String userId, String name);
+
+	User GetErr(String userId) throws Exception;
+
+    Map<String, User> GetUserMap(List<String> userIdList);
+
+    User getUser(int usercode);
+
+    User queryUser(User user);
+
+    Map<String, User> queryAll();
+
+    int Calc(int a,int b);
+
+    Response<Integer> Sum(int a, int b);
+}
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java b/examples/generic/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
rename to examples/generic/java-server/src/main/java/com/ikurento/user/UserProviderAnotherImpl.java
diff --git a/examples/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java b/examples/generic/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
similarity index 100%
rename from examples/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
rename to examples/generic/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
diff --git a/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml b/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f8dd13a833e6095485d0504e21cec272a3c9a288
--- /dev/null
+++ b/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ - Copyright 1999-2011 Alibaba Group.
+ -
+ - Licensed 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	   xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+	<!-- 应用名 -->
+	<dubbo:application name="user-info-server"/>
+	<!-- 连接到哪个本地注册中心 -->
+	<dubbo:registry id="ikurento"  address="zookeeper://127.0.0.1:2181" />
+	<dubbo:registry id="ikurento2"  address="zookeeper://127.0.0.1:2182" />
+	<!-- 用dubbo协议在20880端口暴露服务 -->
+    <!-- dubbo:protocol host="127.0.0.1" / -->
+	<dubbo:protocol id="dubbo" name="dubbo" host="127.0.0.1" port="20010" />
+	<dubbo:protocol id="jsonrpc" name="jsonrpc" host="127.0.0.1" port="10010" />
+	<!-- 声明需要暴露的服务接口 -->
+	<dubbo:service id="aaa" registry="ikurento" timeout="3000" interface="com.ikurento.user.UserProvider" ref="demoService"/>
+	<dubbo:service id="bbb" registry="ikurento" timeout="3000" interface="com.ikurento.user.UserProvider" ref="otherService" version="2.0"/>
+	<dubbo:service id="ccc" registry="ikurento" timeout="3000" interface="com.ikurento.user.UserProvider" ref="otherService" group="as" version="2.0"/>
+
+	<bean id="demoService" class="com.ikurento.user.UserProviderImpl" />
+	<bean id="otherService" class="com.ikurento.user.UserProviderAnotherImpl"/>
+
+</beans>
diff --git a/examples/generic/java-server/src/main/resources/log4j.properties b/examples/generic/java-server/src/main/resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..13c80493329261ea677de77624b363bf99c82652
--- /dev/null
+++ b/examples/generic/java-server/src/main/resources/log4j.properties
@@ -0,0 +1,20 @@
+## Logger configure file for myproject
+log.dir=logs/
+datestamp=yyyy-MM-dd/HH:mm:ss.SSS
+
+log4j.rootLogger=DEBUG, file, console
+
+log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.file.threshold=DEBUG
+log4j.appender.file.File=${log.dir}/log4j.log
+log4j.appender.file.DatePattern=-yyyyMMddHH
+log4j.appender.file.ImmediateFlush=true
+log4j.appender.file.Append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
diff --git a/examples/helloworld/dubbo/go-client/app/client.go b/examples/helloworld/dubbo/go-client/app/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..b416edb5a9b77c2782af01de854bc0c40b4b00bb
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/app/client.go
@@ -0,0 +1,54 @@
+/*
+ * 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 main
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+import (
+	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+	"github.com/apache/dubbo-go/config"
+	_ "github.com/apache/dubbo-go/protocol/dubbo"
+	_ "github.com/apache/dubbo-go/registry/protocol"
+
+	_ "github.com/apache/dubbo-go/filter/impl"
+
+	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
+	_ "github.com/apache/dubbo-go/cluster/loadbalance"
+	_ "github.com/apache/dubbo-go/registry/zookeeper"
+)
+
+// they are necessary:
+// 		export CONF_CONSUMER_FILE_PATH="xxx"
+// 		export APP_LOG_CONF_FILE="xxx"
+func main() {
+
+	config.Load()
+	time.Sleep(3e9)
+
+	println("\n\n\nstart to test dubbo")
+	user := &User{}
+	err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Printf("response result: %v\n", user)
+}
diff --git a/examples/helloworld/dubbo/go-client/app/user.go b/examples/helloworld/dubbo/go-client/app/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..9820dbc08b0f52af9a6d4f9fa364344f0649fbc8
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/app/user.go
@@ -0,0 +1,57 @@
+/*
+ * 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 main
+
+import (
+	"context"
+	"time"
+)
+
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+	"github.com/apache/dubbo-go/config"
+)
+
+var userProvider = new(UserProvider)
+
+func init() {
+	config.SetConsumerService(userProvider)
+	hessian.RegisterPOJO(&User{})
+}
+
+type User struct {
+	Id   string
+	Name string
+	Age  int32
+	Time time.Time
+}
+
+type UserProvider struct {
+	GetUser func(ctx context.Context, req []interface{}, rsp *User) error
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+func (User) JavaClassName() string {
+	return "com.ikurento.user.User"
+}
diff --git a/examples/helloworld/dubbo/go-client/assembly/bin/load.sh b/examples/helloworld/dubbo/go-client/assembly/bin/load.sh
new file mode 100644
index 0000000000000000000000000000000000000000..07d5d15eac7b7974845e36c3807e7ec55875de65
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/bin/load.sh
@@ -0,0 +1,196 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : dubbogo app devops script
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-05-13 02:01
+# FILE    : load.sh
+# ******************************************************
+
+APP_NAME="APPLICATION_NAME"
+APP_ARGS=""
+SLEEP_INTERVAL=5
+MAX_LIFETIME=4000
+
+PROJECT_HOME=""
+OS_NAME=`uname`
+if [[ ${OS_NAME} != "Windows" ]]; then
+    PROJECT_HOME=`pwd`
+    PROJECT_HOME=${PROJECT_HOME}"/"
+else
+    APP_NAME="APPLICATION_NAME.exe"
+fi
+
+export CONF_CONSUMER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE"
+export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
+# export GOTRACEBACK=system
+# export GODEBUG=gctrace=1
+
+usage() {
+    echo "Usage: $0 start [conf suffix]"
+    echo "       $0 stop"
+    echo "       $0 term"
+    echo "       $0 restart"
+    echo "       $0 list"
+    echo "       $0 monitor"
+    echo "       $0 crontab"
+    exit
+}
+
+start() {
+    arg=$1
+    if [ "$arg" = "" ];then
+        echo "No registry type! Default client.yml!"
+    else
+        export CONF_CONSUMER_FILE_PATH=${CONF_CONSUMER_FILE_PATH//\.yml/\_$arg\.yml}
+    fi
+    if [ ! -f "${CONF_CONSUMER_FILE_PATH}" ];then
+        echo $CONF_CONSUMER_FILE_PATH" is not existing!"
+        return
+    fi
+    APP_LOG_PATH=${PROJECT_HOME}"logs/"
+    mkdir -p ${APP_LOG_PATH}
+    APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
+    chmod u+x ${APP_BIN}
+    # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
+    CMD="${APP_BIN}"
+    eval ${CMD}
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    CUR=`date +%FT%T`
+    if [ "${PID}" != "" ]; then
+        for p in ${PID}
+        do
+            echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
+        done
+    fi
+}
+
+stop() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    if [ "${PID}" != "" ];
+    then
+        for ps in ${PID}
+        do
+            echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
+            kill -2 ${ps}
+        done
+    fi
+}
+
+
+term() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    if [ "${PID}" != "" ];
+    then
+        for ps in ${PID}
+        do
+            echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
+            kill -9 ${ps}
+        done
+    fi
+}
+
+list() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
+    fi
+
+    if [ "${PID}" != "" ]; then
+        echo "list ${APP_NAME}"
+
+        if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
+            echo "index: user, pid, start, duration"
+        else
+            echo "index: PID, WINPID, UID, STIME, COMMAND"
+        fi
+        idx=0
+        for ps in ${PID}
+        do
+            echo "${idx}: ${ps}"
+            ((idx ++))
+        done
+    fi
+}
+
+monitor() {
+    idx=0
+    while true; do
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+        if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+            PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+        fi
+        if [[ "${PID}" == "" ]]; then
+            start
+            idx=0
+        fi
+
+        ((LIFE=idx*${SLEEP_INTERVAL}))
+        echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
+        ((idx ++))
+        sleep ${SLEEP_INTERVAL}
+    done
+}
+
+crontab() {
+    idx=0
+    while true; do
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+        if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+            PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+        fi
+        if [[ "${PID}" == "" ]]; then
+            start
+            idx=0
+        fi
+
+        ((LIFE=idx*${SLEEP_INTERVAL}))
+        echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
+        ((idx ++))
+        sleep ${SLEEP_INTERVAL}
+        if [[ ${LIFE} -gt ${MAX_LIFETIME} ]]; then
+            kill -9 ${PID}
+        fi
+    done
+}
+
+opt=$1
+case C"$opt" in
+    Cstart)
+        start $2
+        ;;
+    Cstop)
+        stop
+        ;;
+    Cterm)
+        term
+        ;;
+    Crestart)
+        term
+        start $2
+        ;;
+    Clist)
+        list
+        ;;
+    Cmonitor)
+        monitor
+        ;;
+    Ccrontab)
+        crontab
+        ;;
+    C*)
+        usage
+        ;;
+esac
+
diff --git a/examples/helloworld/dubbo/go-client/assembly/common/app.properties b/examples/helloworld/dubbo/go-client/assembly/common/app.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6bbd6db850ceeaf5ff873fee01a3578237cbd557
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/common/app.properties
@@ -0,0 +1,17 @@
+# dubbogo application configure script
+# ******************************************************
+# DESC    : dubbogo environment variable
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:29
+# FILE    : app.properties
+# ******************************************************
+
+export TARGET_EXEC_NAME="user_info_client"
+# BUILD_PACKAGE="dubbogo-examples/user-info/client/app"
+export BUILD_PACKAGE="app"
+
+export TARGET_CONF_FILE="conf/client.yml"
+export TARGET_LOG_CONF_FILE="conf/log.yml"
diff --git a/examples/helloworld/dubbo/go-client/assembly/common/build.sh b/examples/helloworld/dubbo/go-client/assembly/common/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..e72418297ad2f0ac6985476b5a8d5e03b9e7584e
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/common/build.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:28
+# FILE    : build.sh
+# ******************************************************
+
+rm -rf target/
+
+PROJECT_HOME=`pwd`
+TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
+
+TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
+version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
+if [[ ${GOOS} == "windows" ]]; then
+    TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
+fi
+TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
+if [[ $PROFILE == "dev" ||  $PROFILE == "test" ]]; then
+    # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
+    # GFLAGS=-gcflags "-N -l" -race -v
+    # GFLAGS="-gcflags \"-N -l\" -v"
+    cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
+else
+    # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
+    # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
+    # -w基本没啥损失。-s的损失就有点大了。
+    cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
+fi
+
+TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
+
+mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
+
+SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
+BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
+CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
+
+mkdir -p ${SBIN_DIR}
+mkdir -p ${CONF_DIR}
+
+mv ${TARGET_NAME} ${SBIN_DIR}
+cp -r assembly/bin ${BIN_DIR}
+cd ${BIN_DIR}/bin/ && mv load.sh load_${TARGET_EXEC_NAME}.sh && cd -
+
+platform=$(uname)
+# modify APPLICATION_NAME
+if [ ${platform} == "Darwin" ]; then
+    sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
+fi
+
+# modify TARGET_CONF_FILE
+if [ ${platform} == "Darwin" ]; then
+    sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
+fi
+
+# modify TARGET_LOG_CONF_FILE
+if [ ${platform} == "Darwin" ]; then
+    sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
+fi
+
+cp -r profiles/${PROFILE}/* ${CONF_DIR}
+
+cd ${TARGET_FOLDER}
+
+tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
+
diff --git a/examples/helloworld/dubbo/go-client/assembly/linux/dev.sh b/examples/helloworld/dubbo/go-client/assembly/linux/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..3373f01b948b708cd7bc1958c9d56a9042c60a68
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/linux/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-18 13:24
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="dev"
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/linux/release.sh b/examples/helloworld/dubbo/go-client/assembly/linux/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..34867b8b3488778cd76a1dc7802393dcab6b0df0
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/linux/release.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="release"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/linux/test.sh b/examples/helloworld/dubbo/go-client/assembly/linux/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1bbbefd1e14e08c16deaf859e2841f4d1fe88e9c
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/linux/test.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="test"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/mac/dev.sh b/examples/helloworld/dubbo/go-client/assembly/mac/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b68ac83b6524a6713cd90c4fc5968fe64b1a9545
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/mac/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-18 13:24
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+export PROFILE="dev"
+
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+	. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+	sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/mac/release.sh b/examples/helloworld/dubbo/go-client/assembly/mac/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..688288b3b1b989e8af70a3674b34ea8e0668f3b4
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/mac/release.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+export PROFILE="release"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/mac/test.sh b/examples/helloworld/dubbo/go-client/assembly/mac/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..56d6c11ecd6a1dc5984c74b88c10be9239e57428
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/mac/test.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+export PROFILE="test"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh b/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..91cf6f23bcbecb26db798469a30529261aabbbb6
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-18 13:24
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+export PROFILE="dev"
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/windows/release.sh b/examples/helloworld/dubbo/go-client/assembly/windows/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f317720bd53d9c9e5f8f484b6eb682c9c736af0c
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/windows/release.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+export PROFILE="release"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-client/assembly/windows/test.sh b/examples/helloworld/dubbo/go-client/assembly/windows/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7dd2bec5260e647b57a46aaa37acc098babff068
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/assembly/windows/test.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+export PROFILE="test"
+export PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+  . ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+  sh ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/dubbo/go-client/profiles/dev/client.yml b/examples/helloworld/dubbo/go-client/profiles/dev/client.yml
similarity index 77%
rename from examples/dubbo/go-client/profiles/dev/client.yml
rename to examples/helloworld/dubbo/go-client/profiles/dev/client.yml
index 1595f23c34d3a374c47678ecc7350696e1d8b2c9..fed05b09734c41ef7b53ad2d88a953f997d50735 100644
--- a/examples/dubbo/go-client/profiles/dev/client.yml
+++ b/examples/helloworld/dubbo/go-client/profiles/dev/client.yml
@@ -17,30 +17,25 @@ application_config:
   environment : "dev"
 
 registries :
-  "hangzhouzk":
-    # 对应java配置中address属性的zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+  "demoZk":
     protocol: "zookeeper"
     timeout	: "3s"
     address: "127.0.0.1:2181"
     username: ""
     password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
+
 
 references:
   "UserProvider":
     # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-    registry: "hangzhouzk"
+    registry: "demoZk"
     protocol : "dubbo"
     interface : "com.ikurento.user.UserProvider"
     cluster: "failover"
     methods :
-      - name: "GetUser"
-        retries: 3
+    - name: "GetUser"
+      retries: 3
+
 
 protocol_conf:
   dubbo:
@@ -48,7 +43,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
diff --git a/examples/helloworld/dubbo/go-client/profiles/dev/log.yml b/examples/helloworld/dubbo/go-client/profiles/dev/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..59fa4279ad85272c4c49d532beaf23b74d00f58a
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/profiles/dev/log.yml
@@ -0,0 +1,28 @@
+
+level: "debug"
+development: true
+disableCaller: false
+disableStacktrace: false
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/dubbo/go-client/profiles/release/client.yml b/examples/helloworld/dubbo/go-client/profiles/release/client.yml
similarity index 87%
rename from examples/dubbo/go-client/profiles/release/client.yml
rename to examples/helloworld/dubbo/go-client/profiles/release/client.yml
index 7a193ea64d783220f016c6b6220d602a5c586129..02bf722754632f12d0e8e7cab3979ce360ffd7c7 100644
--- a/examples/dubbo/go-client/profiles/release/client.yml
+++ b/examples/helloworld/dubbo/go-client/profiles/release/client.yml
@@ -23,20 +23,13 @@ registries :
     address: "127.0.0.1:2181"
     username: ""
     password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
+
 
 references:
   "UserProvider":
     # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
     registry: "hangzhouzk"
     protocol : "dubbo"
-#    version: "2.0"
-#    group: "as"
     interface : "com.ikurento.user.UserProvider"
     cluster: "failover"
     methods :
@@ -49,7 +42,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
diff --git a/examples/helloworld/dubbo/go-client/profiles/release/log.yml b/examples/helloworld/dubbo/go-client/profiles/release/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e0514be020eedf594d99d112183cdd5ce199e46d
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/profiles/release/log.yml
@@ -0,0 +1,28 @@
+
+level: "warn"
+development: true
+disableCaller: true
+disableStacktrace: true
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/dubbo/go-client/profiles/test/client.yml b/examples/helloworld/dubbo/go-client/profiles/test/client.yml
similarity index 84%
rename from examples/dubbo/go-client/profiles/test/client.yml
rename to examples/helloworld/dubbo/go-client/profiles/test/client.yml
index 24ede19d7d2365fb9c7d92d31bc312cfc7935388..417a388c6cfb38a6a1563e9c4ab8856e4b2f30f8 100644
--- a/examples/dubbo/go-client/profiles/test/client.yml
+++ b/examples/helloworld/dubbo/go-client/profiles/test/client.yml
@@ -23,25 +23,17 @@ registries :
     address: "127.0.0.1:2181"
     username: ""
     password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
 
 references:
   "UserProvider":
     # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
     registry: "hangzhouzk"
     protocol : "dubbo"
-#    version: "2.0"
-#    group: "as"
     interface : "com.ikurento.user.UserProvider"
     cluster: "failover"
     methods :
-      - name: "GetUser"
-        retries: 3
+    - name: "GetUser"
+      retries: 3
 
 protocol_conf:
   dubbo:
@@ -49,7 +41,6 @@ protocol_conf:
     connection_number: 2
     heartbeat_period: "5s"
     session_timeout: "20s"
-    fail_fast_timeout: "5s"
     pool_size: 64
     pool_ttl: 600
     getty_session_param:
diff --git a/examples/helloworld/dubbo/go-client/profiles/test/log.yml b/examples/helloworld/dubbo/go-client/profiles/test/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..baee0b7248484e425f88f35ab128212c931ff85e
--- /dev/null
+++ b/examples/helloworld/dubbo/go-client/profiles/test/log.yml
@@ -0,0 +1,28 @@
+
+level: "info"
+development: false
+disableCaller: false
+disableStacktrace: true
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/helloworld/dubbo/go-server/app/server.go b/examples/helloworld/dubbo/go-server/app/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..f02a6ba05e8723410c985823caafe88192f5af7e
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/app/server.go
@@ -0,0 +1,77 @@
+/*
+ * 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 main
+
+import (
+	"fmt"
+	"os"
+	"os/signal"
+	"syscall"
+	"time"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config"
+	_ "github.com/apache/dubbo-go/protocol/dubbo"
+	_ "github.com/apache/dubbo-go/registry/protocol"
+
+	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+	_ "github.com/apache/dubbo-go/filter/impl"
+
+	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
+	_ "github.com/apache/dubbo-go/cluster/loadbalance"
+	_ "github.com/apache/dubbo-go/registry/zookeeper"
+)
+
+var (
+	survivalTimeout = int(3e9)
+)
+
+// they are necessary:
+// 		export CONF_PROVIDER_FILE_PATH="xxx"
+// 		export APP_LOG_CONF_FILE="xxx"
+func main() {
+
+	config.Load()
+
+	initSignal()
+}
+
+func initSignal() {
+	signals := make(chan os.Signal, 1)
+	// It is not possible to block SIGKILL or syscall.SIGSTOP
+	signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
+	for {
+		sig := <-signals
+		logger.Infof("get signal %s", sig.String())
+		switch sig {
+		case syscall.SIGHUP:
+			// reload()
+		default:
+			go time.AfterFunc(time.Duration(survivalTimeout), func() {
+				logger.Warnf("app exit now by force...")
+				os.Exit(1)
+			})
+
+			// The program exits normally or timeout forcibly exits.
+			fmt.Println("provider app exit now...")
+			return
+		}
+	}
+}
diff --git a/examples/helloworld/dubbo/go-server/app/user.go b/examples/helloworld/dubbo/go-server/app/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..ee7aa1c7ed33654ae38bdf2d8fd77257a70e3e85
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/app/user.go
@@ -0,0 +1,59 @@
+/*
+ * 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 main
+
+import (
+	"context"
+	"time"
+)
+
+import (
+	"github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+	"github.com/apache/dubbo-go/config"
+)
+
+func init() {
+	config.SetProviderService(new(UserProvider))
+	// ------for hessian2------
+	hessian.RegisterPOJO(&User{})
+}
+
+type User struct {
+	Id   string
+	Name string
+	Age  int32
+	Time time.Time
+}
+
+type UserProvider struct {
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) {
+	return &User{"A001", "Alex Stocks", 18, time.Now()}, nil
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+func (u User) JavaClassName() string {
+	return "com.ikurento.user.User"
+}
diff --git a/examples/helloworld/dubbo/go-server/assembly/bin/load.sh b/examples/helloworld/dubbo/go-server/assembly/bin/load.sh
new file mode 100644
index 0000000000000000000000000000000000000000..47fc5e38ded155a43c30b8cbf4d2a5ae04b58d0c
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/bin/load.sh
@@ -0,0 +1,144 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : dubbogo app devops script
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-05-13 02:01
+# FILE    : load.sh
+# ******************************************************
+
+APP_NAME="APPLICATION_NAME"
+APP_ARGS=""
+
+
+PROJECT_HOME=""
+OS_NAME=`uname`
+if [[ ${OS_NAME} != "Windows" ]]; then
+    PROJECT_HOME=`pwd`
+    PROJECT_HOME=${PROJECT_HOME}"/"
+fi
+
+export CONF_PROVIDER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE"
+export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
+
+usage() {
+    echo "Usage: $0 start [conf suffix]"
+    echo "       $0 stop"
+    echo "       $0 term"
+    echo "       $0 restart"
+    echo "       $0 list"
+    echo "       $0 monitor"
+    echo "       $0 crontab"
+    exit
+}
+
+start() {
+    arg=$1
+    if [ "$arg" = "" ];then
+        echo "No registry type! Default server.yml!"
+    else
+        export CONF_PROVIDER_FILE_PATH=${CONF_PROVIDER_FILE_PATH//\.yml/\_$arg\.yml}
+    fi
+    if [ ! -f "${CONF_PROVIDER_FILE_PATH}" ];then
+        echo $CONF_PROVIDER_FILE_PATH" is not existing!"
+        return
+    fi
+    APP_LOG_PATH="${PROJECT_HOME}logs/"
+    mkdir -p ${APP_LOG_PATH}
+    APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
+    chmod u+x ${APP_BIN}
+    # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
+    CMD="${APP_BIN}"
+    eval ${CMD}
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    CUR=`date +%FT%T`
+    if [ "${PID}" != "" ]; then
+        for p in ${PID}
+        do
+            echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
+        done
+    fi
+}
+
+stop() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    if [ "${PID}" != "" ];
+    then
+        for ps in ${PID}
+        do
+            echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
+            kill -2 ${ps}
+        done
+    fi
+}
+
+
+term() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
+    fi
+    if [ "${PID}" != "" ];
+    then
+        for ps in ${PID}
+        do
+            echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
+            kill -9 ${ps}
+        done
+    fi
+}
+
+list() {
+    PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
+    if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
+        PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
+    fi
+
+    if [ "${PID}" != "" ]; then
+        echo "list ${APP_NAME}"
+
+        if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
+            echo "index: user, pid, start, duration"
+    else
+        echo "index: PID, WINPID, UID, STIME, COMMAND"
+    fi
+        idx=0
+        for ps in ${PID}
+        do
+            echo "${idx}: ${ps}"
+            ((idx ++))
+        done
+    fi
+}
+
+opt=$1
+case C"$opt" in
+    Cstart)
+        start $2
+        ;;
+    Cstop)
+        stop
+        ;;
+    Cterm)
+        term
+        ;;
+    Crestart)
+        term
+        start $2
+        ;;
+    Clist)
+        list
+        ;;
+    C*)
+        usage
+        ;;
+esac
+
diff --git a/examples/helloworld/dubbo/go-server/assembly/common/app.properties b/examples/helloworld/dubbo/go-server/assembly/common/app.properties
new file mode 100644
index 0000000000000000000000000000000000000000..dffb755b0811dd140d3f04e232f5f80ff60181df
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/common/app.properties
@@ -0,0 +1,17 @@
+# dubbogo application configure script
+# ******************************************************
+# DESC    : application environment variable
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:29
+# FILE    : app.properties
+# ******************************************************
+
+TARGET_EXEC_NAME="user_info_server"
+# BUILD_PACKAGE="dubbogo-examples/user-info/server/app"
+BUILD_PACKAGE="app"
+
+TARGET_CONF_FILE="conf/server.yml"
+TARGET_LOG_CONF_FILE="conf/log.yml"
diff --git a/examples/helloworld/dubbo/go-server/assembly/common/build.sh b/examples/helloworld/dubbo/go-server/assembly/common/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..15ac904f7c265d942d7018439719af7e7391aa41
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/common/build.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:28
+# FILE    : build.sh
+# ******************************************************
+
+rm -rf target/
+
+PROJECT_HOME=`pwd`
+TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
+
+TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
+version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
+if [[ ${GOOS} == "windows" ]]; then
+    TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
+fi
+TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
+if [[ $PROFILE = "test" ]]; then
+    # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
+    # GFLAGS=-gcflags "-N -l" -race -v
+    # GFLAGS="-gcflags \"-N -l\" -v"
+    cd ${BUILD_PACKAGE} && go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
+else
+    # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
+    # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
+    # -w基本没啥损失。-s的损失就有点大了。
+    cd ${BUILD_PACKAGE} && go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
+fi
+
+TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
+
+mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
+
+SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
+BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
+CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
+
+mkdir -p ${SBIN_DIR}
+mkdir -p ${CONF_DIR}
+
+mv ${TARGET_NAME} ${SBIN_DIR}
+cp -r assembly/bin ${BIN_DIR}
+# modify APPLICATION_NAME
+# OS=`uname`
+# if [[ $OS=="Darwin" ]]; then
+if [ "$(uname)" == "Darwin" ]; then
+    sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
+fi
+# modify TARGET_CONF_FILE
+if [ "$(uname)" == "Darwin" ]; then
+    sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
+fi
+# modify TARGET_LOG_CONF_FILE
+if [ "$(uname)" == "Darwin" ]; then
+    sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
+else
+    sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
+fi
+
+cp -r profiles/${PROFILE}/* ${CONF_DIR}
+
+cd ${TARGET_FOLDER}
+
+tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
+
diff --git a/examples/helloworld/dubbo/go-server/assembly/linux/dev.sh b/examples/helloworld/dubbo/go-server/assembly/linux/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..55886f09fb4873be84cfa46aae592f5f000120a4
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/linux/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2018-06-24 17:32
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+PROFILE=dev
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/linux/release.sh b/examples/helloworld/dubbo/go-server/assembly/linux/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9772ad9614583917d62beba2db9fcaefea63e1ed
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/linux/release.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:25
+# FILE    : release.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+PROFILE=release
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/linux/test.sh b/examples/helloworld/dubbo/go-server/assembly/linux/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2fc4a98862bee5ef11a23e1b74058627a899181d
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/linux/test.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=linux
+export GOARCH=amd64
+
+PROFILE=test
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/mac/dev.sh b/examples/helloworld/dubbo/go-server/assembly/mac/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5dfa78490b895ce556c809ead32b6f517a5f1450
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/mac/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2018-06-24 17:32
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+PROFILE=dev
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/mac/release.sh b/examples/helloworld/dubbo/go-server/assembly/mac/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1ec21c7b511ccce9eddfac22a2374b57a7a697bf
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/mac/release.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:25
+# FILE    : release.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+PROFILE=release
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/mac/test.sh b/examples/helloworld/dubbo/go-server/assembly/mac/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..d34914c7dbed0e442b4accf51a3ecdf7c2984db8
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/mac/test.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:25
+# FILE    : release.sh
+# ******************************************************
+
+set -e
+
+export GOOS=darwin
+export GOARCH=amd64
+
+PROFILE=test
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
+
diff --git a/examples/helloworld/dubbo/go-server/assembly/windows/dev.sh b/examples/helloworld/dubbo/go-server/assembly/windows/dev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..97fbb6f698e500ad08d971b13cc1ffd00cd97803
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/windows/dev.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for dev env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2018-06-24 17:34
+# FILE    : dev.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+PROFILE=dev
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/windows/release.sh b/examples/helloworld/dubbo/go-server/assembly/windows/release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..782cb10c7828eb277b5905f10f8dd6ad1c2d6bed
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/windows/release.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for release env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:25
+# FILE    : release.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+PROFILE=release
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/assembly/windows/test.sh b/examples/helloworld/dubbo/go-server/assembly/windows/test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2037ddecf2545f1543d5d28be728fb0899722098
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/assembly/windows/test.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# ******************************************************
+# DESC    : build script for test env
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2016-07-12 16:34
+# FILE    : test.sh
+# ******************************************************
+
+
+set -e
+
+export GOOS=windows
+export GOARCH=amd64
+
+PROFILE=test
+
+PROJECT_HOME=`pwd`
+
+if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
+. ${PROJECT_HOME}/assembly/common/app.properties
+fi
+
+
+if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
+. ${PROJECT_HOME}/assembly/common/build.sh
+fi
diff --git a/examples/helloworld/dubbo/go-server/profiles/dev/log.yml b/examples/helloworld/dubbo/go-server/profiles/dev/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..59fa4279ad85272c4c49d532beaf23b74d00f58a
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/profiles/dev/log.yml
@@ -0,0 +1,28 @@
+
+level: "debug"
+development: true
+disableCaller: false
+disableStacktrace: false
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/helloworld/dubbo/go-server/profiles/dev/server.yml b/examples/helloworld/dubbo/go-server/profiles/dev/server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..be7eedeaa3fd186f4cd2ea264b31429165e55bf1
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/profiles/dev/server.yml
@@ -0,0 +1,57 @@
+# dubbo server yaml configure file
+
+
+# application config
+application_config:
+  organization : "ikurento.com"
+  name : "BDTService"
+  module : "dubbogo user-info server"
+  version : "0.0.1"
+  owner : "ZX"
+  environment : "dev"
+
+registries :
+  "demoZk":
+    protocol: "zookeeper"
+    timeout	: "3s"
+    address: "127.0.0.1:2181"
+
+services:
+  "UserProvider":
+    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+    registry: "demoZk"
+    protocol : "dubbo"
+    # 相当于dubbo.xml中的interface
+    interface : "com.ikurento.user.UserProvider"
+    loadbalance: "random"
+    warmup: "100"
+    cluster: "failover"
+    methods:
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
+
+protocols:
+  "dubbo":
+    name: "dubbo"
+    port: 20000
+
+
+protocol_conf:
+  dubbo:
+    session_number: 700
+    session_timeout: "20s"
+    getty_session_param:
+      compress_encoding: false
+      tcp_no_delay: true
+      tcp_keep_alive: true
+      keep_alive_period: "120s"
+      tcp_r_buf_size: 262144
+      tcp_w_buf_size: 65536
+      pkg_rq_size: 1024
+      pkg_wq_size: 512
+      tcp_read_timeout: "1s"
+      tcp_write_timeout: "5s"
+      wait_timeout: "1s"
+      max_msg_len: 1024
+      session_name: "server"
diff --git a/examples/helloworld/dubbo/go-server/profiles/release/log.yml b/examples/helloworld/dubbo/go-server/profiles/release/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e0514be020eedf594d99d112183cdd5ce199e46d
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/profiles/release/log.yml
@@ -0,0 +1,28 @@
+
+level: "warn"
+development: true
+disableCaller: true
+disableStacktrace: true
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/dubbo/go-server/profiles/release/server.yml b/examples/helloworld/dubbo/go-server/profiles/release/server.yml
similarity index 89%
rename from examples/dubbo/go-server/profiles/release/server.yml
rename to examples/helloworld/dubbo/go-server/profiles/release/server.yml
index 3db12902f1d349e1703f2f977c682c61b0d35938..4786e83669046babbfc4758829155d8f4ce3a438 100644
--- a/examples/dubbo/go-server/profiles/release/server.yml
+++ b/examples/helloworld/dubbo/go-server/profiles/release/server.yml
@@ -17,12 +17,6 @@ registries :
     address: "127.0.0.1:2181"
     username: ""
     password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
 
 
 services:
@@ -40,6 +34,7 @@ services:
         retries: 1
         loadbalance: "random"
 
+
 protocols:
   "dubbo1":
       name: "dubbo"
@@ -50,7 +45,6 @@ protocols:
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
     getty_session_param:
       compress_encoding: false
diff --git a/examples/helloworld/dubbo/go-server/profiles/test/log.yml b/examples/helloworld/dubbo/go-server/profiles/test/log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..baee0b7248484e425f88f35ab128212c931ff85e
--- /dev/null
+++ b/examples/helloworld/dubbo/go-server/profiles/test/log.yml
@@ -0,0 +1,28 @@
+
+level: "info"
+development: false
+disableCaller: false
+disableStacktrace: true
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/examples/dubbo/go-server/profiles/test/server.yml b/examples/helloworld/dubbo/go-server/profiles/test/server.yml
similarity index 80%
rename from examples/dubbo/go-server/profiles/test/server.yml
rename to examples/helloworld/dubbo/go-server/profiles/test/server.yml
index 12f10e004c6b1b5ea1afcf37fe79306bd4d10d82..ba6eb2b8005a4dc2d655f44ec38b93a01072d4f1 100644
--- a/examples/dubbo/go-server/profiles/test/server.yml
+++ b/examples/helloworld/dubbo/go-server/profiles/test/server.yml
@@ -17,12 +17,7 @@ registries :
     address: "127.0.0.1:2181"
     username: ""
     password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
+
 
 
 services:
@@ -36,21 +31,20 @@ services:
     warmup: "100"
     cluster: "failover"
     methods:
-      - name: "GetUser"
-        retries: 1
-        loadbalance: "random"
+    - name: "GetUser"
+      retries: 1
+      loadbalance: "random"
 
 protocols:
   "dubbo1":
-      name: "dubbo"
-  #    ip : "127.0.0.1"
-      port: 20000
+    name: "dubbo"
+    #    ip : "127.0.0.1"
+    port: 20000
 
 
 protocol_conf:
   dubbo:
     session_number: 700
-    fail_fast_timeout: "5s"
     session_timeout: "20s"
     getty_session_param:
       compress_encoding: false
diff --git a/examples/helloworld/dubbo/java-server/build.sh b/examples/helloworld/dubbo/java-server/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..0c197da639c1c1d9375e18c24dd73366c49deefe
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/build.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# ******************************************************
+# EMAIL   : alexstocks@foxmail.com
+# FILE    : build.sh
+# ******************************************************
+
+# mvn dependency:sources
+mvn clean package -Dmaven.test.skip
+# mvn -X clean compile package -DskipTests=true
diff --git a/examples/helloworld/dubbo/java-server/pom.xml b/examples/helloworld/dubbo/java-server/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..975157865e59f24693d755dd20b0aac4b179a793
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/pom.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.ikurento</groupId>
+    <artifactId>user-info-server</artifactId>
+    <packaging>jar</packaging>
+    <version>0.2.0</version>
+    <description>The demo provider module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+
+        <dubbo-version>2.6.5</dubbo-version>
+        <dubbo-jsonrpc-version>1.0.1</dubbo-jsonrpc-version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>dubbo-dependencies-bom</artifactId>
+                <version>${dubbo-version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.7.25</version>
+		</dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${dubbo-version}</version>
+            <exclusions>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-framework</artifactId>
+            <version>2.12.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.qianmi</groupId>
+            <artifactId>dubbo-rpc-jsonrpc</artifactId>
+            <version>${dubbo-jsonrpc-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty</artifactId>
+            <version>6.1.26</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.9.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.9.9</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.sgroschupf</groupId>
+            <artifactId>zkclient</artifactId>
+            <version>0.1</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>org.apache.zookeeper</artifactId>
+                    <groupId>zookeeper</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>3.4.14</version>
+        </dependency>
+
+    </dependencies>
+
+    <repositories>
+		<repository>
+            <id>nexus-aliyu</id>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+		<releases>
+			<enabled>true</enabled>
+		</releases>
+		<snapshots>
+			<enabled>false</enabled>
+		</snapshots>
+		</repository>
+    </repositories>
+    <pluginRepositories>
+		  <pluginRepository>
+              <id>nexus-aliyu</id>
+              <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+			<releases>
+			<enabled>true</enabled>
+			</releases>
+			<snapshots>
+			<enabled>false</enabled>
+			</snapshots>
+		  </pluginRepository>
+		</pluginRepositories>
+
+
+    <build>
+
+        <plugins>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>unpack</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>com.alibaba</groupId>
+                                    <artifactId>dubbo</artifactId>
+                                    <version>${dubbo-version}</version>
+                                    <outputDirectory>${project.build.directory}/dubbo</outputDirectory>
+                                    <includes>META-INF/assembly/**</includes>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
+
+
diff --git a/examples/helloworld/dubbo/java-server/script/debug.sh b/examples/helloworld/dubbo/java-server/script/debug.sh
new file mode 100644
index 0000000000000000000000000000000000000000..27c5d800d846018127e762944151aa8e9ad4495d
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/script/debug.sh
@@ -0,0 +1,16 @@
+#!/us1r/bin/env bash
+# ******************************************************
+# DESC    :
+# AUTHOR  : Alex Stocks
+# VERSION : 1.0
+# LICENCE : Apache License 2.0
+# EMAIL   : alexstocks@foxmail.com
+# MOD     : 2017-10-09 21:52
+# FILE    : to debug user info dubbo server
+# ******************************************************
+
+# jdb -classpath /Users/alex/tmp/us/conf:/Users/alex/tmp/us/lib/*:/Users/alex/test/java/dubbo/2.5.4/dubbo-remoting/dubbo-remoting-api/src/main/java/ com.alibaba.dubbo.container.Main
+jdb -classpath /Users/alex/tmp/us/conf:/Users/alex/tmp/us/lib/* -sourcepath /Users/alex/test/java/dubbo/2.5.4/dubbo-remoting/dubbo-remoting-api/src/main/java/:/Users/alex/tmp/java-server/src/main/java com.alibaba.dubbo.container.Main
+# jdb stop at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec:76
+# run
+
diff --git a/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml b/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f01fea20f5391112cccb88c87bfe4ae1b59750a
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml
@@ -0,0 +1,45 @@
+<!--
+ - Copyright 1999-2011 Alibaba Group.
+ -  
+ - Licensed 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.
+-->
+<assembly>
+	<id>assembly</id>
+	<formats>
+		<format>tar.gz</format>
+	</formats>
+	<includeBaseDirectory>true</includeBaseDirectory>
+	<fileSets>
+		<fileSet>
+			<directory>${project.build.directory}/dubbo/META-INF/assembly/bin</directory>
+			<outputDirectory>bin</outputDirectory>
+			<fileMode>0755</fileMode>
+            <directoryMode>0755</directoryMode>
+		</fileSet>
+		<fileSet>
+            <directory>src/main/assembly/conf</directory>
+            <includes>
+                <include>dubbo.properties</include>
+                <include>log4j.*</include>
+            </includes>
+			<outputDirectory>conf</outputDirectory>
+			<fileMode>0644</fileMode>
+            <directoryMode>0755</directoryMode>
+		</fileSet>
+	</fileSets>
+	<dependencySets>
+		<dependencySet>
+			<outputDirectory>lib</outputDirectory>
+		</dependencySet>
+	</dependencySets>
+</assembly>
\ No newline at end of file
diff --git a/examples/helloworld/dubbo/java-server/src/main/assembly/conf/dubbo.properties b/examples/helloworld/dubbo/java-server/src/main/assembly/conf/dubbo.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2826f31303717256725b02a79e1698043709d2f3
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/assembly/conf/dubbo.properties
@@ -0,0 +1,14 @@
+### dubbo注册中心配置 ##
+dubbo.container = log4j,spring
+dubbo.application.name = user-info-server
+dubbo.application.environment = product
+dubbo.application.owner = AlexStocks
+dubbo.registry.address = 127.0.0.1:2181
+dubbo.registry.protocol = zookeeper
+dubbo.consumer.timeout = 10000
+dubbo.provider.timeout = 10000
+dubbo.protocol.name = dubbo
+dubbo.protocol.port = 10000
+
+dubbo.log4j.file = logs/dubbo.log
+dubbo.log4j.level = INFO
diff --git a/examples/helloworld/dubbo/java-server/src/main/assembly/conf/log4j.properties b/examples/helloworld/dubbo/java-server/src/main/assembly/conf/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..13c80493329261ea677de77624b363bf99c82652
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/assembly/conf/log4j.properties
@@ -0,0 +1,20 @@
+## Logger configure file for myproject
+log.dir=logs/
+datestamp=yyyy-MM-dd/HH:mm:ss.SSS
+
+log4j.rootLogger=DEBUG, file, console
+
+log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.file.threshold=DEBUG
+log4j.appender.file.File=${log.dir}/log4j.log
+log4j.appender.file.DatePattern=-yyyyMMddHH
+log4j.appender.file.ImmediateFlush=true
+log4j.appender.file.Append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
diff --git a/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java
new file mode 100644
index 0000000000000000000000000000000000000000..0031f5569fd5f16ded0da6e5426f78805fad4a42
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/Provider.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.ikurento.user;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Provider {
+
+    /**
+     * To get ipv6 address to work, add
+     * System.setProperty("java.net.preferIPv6Addresses", "true");
+     * before running your application.
+     */
+    public static void main(String[] args) throws Exception {
+        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.provider.xml"});
+        context.start();
+        System.in.read(); // press any key to exit
+    }
+}
diff --git a/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/User.java b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..06f3f18f0a8ae940000fae3155e448c3181a0054
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/User.java
@@ -0,0 +1,70 @@
+package com.ikurento.user;
+// ref: https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+import java.util.Date;
+import java.io.Serializable;
+
+public class User implements Serializable  {
+
+    private String id;
+
+    private String name;
+
+    private int age;
+
+    private Date time = new Date();
+
+    public User() {
+    }
+
+    public User(String id, String name, int age) {
+        this.id = id;
+        this.name = name;
+        this.age = age;
+    }
+
+    public User(String id, String name, int age, Date time) {
+        this.id = id;
+        this.name = name;
+        this.age = age;
+        this.time = time;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public Date getTime() {
+        return time;
+    }
+
+    public void setTime(Date time) {
+        this.time = time;
+    }
+
+
+
+    public String toString() {
+        return "User{id:" + id + ", name:" + name + ", age:" + age + ", time:" + time +"}";
+    }
+}
diff --git a/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3301cd642ca58a57ac5e2041ec5f958d383b7fb
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/UserProvider.java
@@ -0,0 +1,9 @@
+package com.ikurento.user;
+// https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+
+public interface UserProvider {
+
+    User GetUser(String userId); // the first alpha is Upper case to compatible with golang.
+
+}
diff --git a/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a394b80a4b767f25e2ff13b2d4cfe7a500f759a
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
@@ -0,0 +1,15 @@
+package com.ikurento.user;
+
+// ref: https://github.com/JoeCao/dubbo_jsonrpc_example/tree/master/dubbo_server/src/main/java/com/ofpay/demo/api
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserProviderImpl implements UserProvider {
+    private static final Logger LOG = LoggerFactory.getLogger("UserLogger"); //Output to user-server.log
+
+    public User GetUser(String userId) {
+        return new User(userId, "zhangsan", 18);
+    }
+
+}
diff --git a/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml b/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fe23e1f3e91d841c30534c82d8d69e6628f6b528
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ - Copyright 1999-2011 Alibaba Group.
+ -
+ - Licensed 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	   xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+	<!-- 应用名 -->
+	<dubbo:application name="user-info-server"/>
+	<!-- 连接到哪个本地注册中心 -->
+	<dubbo:registry id="ikurento"  address="zookeeper://127.0.0.1:2181" />
+	<!-- 用dubbo协议在20880端口暴露服务 -->
+    <!-- dubbo:protocol host="127.0.0.1" / -->
+	<dubbo:protocol id="dubbo" name="dubbo" host="127.0.0.1" port="20010" />
+	<!-- 声明需要暴露的服务接口 -->
+	<dubbo:service id="aaa" registry="ikurento" timeout="3000" interface="com.ikurento.user.UserProvider" ref="demoService"/>
+
+	<bean id="demoService" class="com.ikurento.user.UserProviderImpl" />
+
+</beans>
diff --git a/examples/helloworld/dubbo/java-server/src/main/resources/log4j.properties b/examples/helloworld/dubbo/java-server/src/main/resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..13c80493329261ea677de77624b363bf99c82652
--- /dev/null
+++ b/examples/helloworld/dubbo/java-server/src/main/resources/log4j.properties
@@ -0,0 +1,20 @@
+## Logger configure file for myproject
+log.dir=logs/
+datestamp=yyyy-MM-dd/HH:mm:ss.SSS
+
+log4j.rootLogger=DEBUG, file, console
+
+log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.file.threshold=DEBUG
+log4j.appender.file.File=${log.dir}/log4j.log
+log4j.appender.file.DatePattern=-yyyyMMddHH
+log4j.appender.file.ImmediateFlush=true
+log4j.appender.file.Append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{${datestamp}} %5p: %l - %m%n
+
diff --git a/examples/jsonrpc/go-client/profiles/test/client.yml b/examples/jsonrpc/go-client/profiles/test/client.yml
deleted file mode 100644
index 1b0529c455a9492d68d040632451bd13198552a4..0000000000000000000000000000000000000000
--- a/examples/jsonrpc/go-client/profiles/test/client.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-# dubbo client yaml configure file
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
-    organization : "ikurento.com"
-    name  : "BDTService"
-    module : "dubbogo user-info client"
-    version : "0.0.1"
-    owner : "ZX"
-    environment : "test"
-
-registries :
-  "hangzhouzk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2181"
-    username: ""
-    password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
-
-references:
-  "UserProvider":
-    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-    registry: "hangzhouzk"
-    protocol : "jsonrpc"
-#    version : "2.0"
-#    group: "as"
-    interface : "com.ikurento.user.UserProvider"
-    cluster: "failover"
-    methods :
-      - name: "GetUser"
-        retries: 3
-
-protocol_conf:
-  dubbo:
-    reconnect_interval: 0
-    connection_number: 2
-    heartbeat_period: "5s"
-    session_timeout: "20s"
-    fail_fast_timeout: "5s"
-    pool_size: 64
-    pool_ttl: 600
-    getty_session_param:
-      compress_encoding: false
-      tcp_no_delay: true
-      tcp_keep_alive: true
-      keep_alive_period: "120s"
-      tcp_r_buf_size: 262144
-      tcp_w_buf_size: 65536
-      pkg_rq_size: 1024
-      pkg_wq_size: 512
-      tcp_read_timeout: "1s"
-      tcp_write_timeout: "5s"
-      wait_timeout: "1s"
-      max_msg_len: 10240
-      session_name: "client"
diff --git a/examples/jsonrpc/go-server/app/user.go b/examples/jsonrpc/go-server/app/user.go
deleted file mode 100644
index e86d915417cc54b05faa25ebaa06dae2c5fb6dd1..0000000000000000000000000000000000000000
--- a/examples/jsonrpc/go-server/app/user.go
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 main
-
-import (
-	"context"
-	"fmt"
-	"strconv"
-	"time"
-)
-
-import (
-	perrors "github.com/pkg/errors"
-)
-
-import (
-	"github.com/apache/dubbo-go/config"
-)
-
-type Gender int
-
-func init() {
-	config.SetProviderService(new(UserProvider))
-}
-
-const (
-	MAN = iota
-	WOMAN
-)
-
-var genderStrings = [...]string{
-	"MAN",
-	"WOMAN",
-}
-
-func (g Gender) String() string {
-	return genderStrings[g]
-}
-
-type (
-	User struct {
-		Id    string `json:"id"`
-		Name  string `json:"name"`
-		Age   int    `json:"age"`
-		sex   Gender
-		Birth int    `json:"time"`
-		Sex   string `json:"sex"`
-	}
-
-	UserProvider struct {
-		user map[string]User
-	}
-)
-
-var (
-	DefaultUser = User{
-		Id: "0", Name: "Alex Stocks", Age: 31,
-		// Birth: int(time.Date(1985, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
-		Birth: int(time.Date(1985, 11, 24, 15, 15, 0, 0, time.Local).Unix()),
-		sex:   Gender(MAN),
-	}
-
-	userMap = UserProvider{user: make(map[string]User)}
-)
-
-func init() {
-	DefaultUser.Sex = DefaultUser.sex.String()
-	userMap.user["A000"] = DefaultUser
-	userMap.user["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, sex: MAN}
-	userMap.user["A002"] = User{Id: "002", Name: "Lily", Age: 20, sex: WOMAN}
-	userMap.user["A003"] = User{Id: "113", Name: "Moorse", Age: 30, sex: MAN}
-	for k, v := range userMap.user {
-		v.Birth = int(time.Now().AddDate(-1*v.Age, 0, 0).Unix())
-		v.Sex = userMap.user[k].sex.String()
-		userMap.user[k] = v
-	}
-}
-
-func (u *UserProvider) getUser(userId string) (*User, error) {
-	if user, ok := userMap.user[userId]; ok {
-		return &user, nil
-	}
-
-	return nil, fmt.Errorf("invalid user id:%s", userId)
-}
-
-func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
-	var (
-		err  error
-		user *User
-	)
-
-	println("req:%#v", req)
-	user, err = u.getUser(req[0].(string))
-	if err == nil {
-		*rsp = *user
-		println("rsp:%#v", rsp)
-	}
-	return err
-}
-
-func (u *UserProvider) GetUser0(id string, name string) (User, error) {
-	var err error
-
-	println("id:%s, name:%s", id, name)
-	user, err := u.getUser(id)
-	if err != nil {
-		return User{}, err
-	}
-	if user.Name != name {
-		return User{}, perrors.New("name is not " + user.Name)
-	}
-	return *user, err
-}
-
-func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
-	var err error
-
-	println("req:%#v", req)
-	rsp.Id = strconv.FormatFloat(req[0].(float64), 'f', 0, 64)
-	rsp.Sex = Gender(MAN).String()
-	return err
-}
-
-func (u *UserProvider) GetUser3() error {
-	return nil
-}
-
-func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
-	var err error
-
-	println("req:%s", req)
-	t := req[0].([]interface{})
-	user, err := u.getUser(t[0].(string))
-	if err != nil {
-		return nil, err
-	}
-	println("user:%v", user)
-	user1, err := u.getUser(t[1].(string))
-	if err != nil {
-		return nil, err
-	}
-	println("user1:%v", user1)
-
-	return []User{*user, *user1}, err
-}
-
-func (s *UserProvider) MethodMapper() map[string]string {
-	return map[string]string{
-		"GetUser2": "getUser",
-	}
-}
-
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
-}
-
-func println(format string, args ...interface{}) {
-	fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
-}
diff --git a/examples/jsonrpc/go-server/profiles/dev/server.yml b/examples/jsonrpc/go-server/profiles/dev/server.yml
deleted file mode 100644
index b5384a28a37535bf7493d6ae07166f6da3b4c440..0000000000000000000000000000000000000000
--- a/examples/jsonrpc/go-server/profiles/dev/server.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-application_config:
-    organization : "ikurento.com"
-    name : "BDTService"
-    module : "dubbogo user-info server"
-    version : "0.0.1"
-    owner : "ZX"
-    environment : "dev"
-
-registries :
-  "hangzhouzk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2181"
-    username: ""
-    password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
-
-
-services:
- "UserProvider":
-   # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-   registry: "hangzhouzk"
-   protocol : "jsonrpc"
-  # 相当于dubbo.xml中的interface
-   interface : "com.ikurento.user.UserProvider"
-   loadbalance: "random"
-   warmup: "100"
-   cluster: "failover"
-   methods:
-     - name: "GetUser"
-       retries: 1
-       loadbalance: "random"
-
-protocols:
-  #-   name: "dubbo"
-  #    ip : "127.0.0.1"
-  #    port : 20000
-  "jsonrpc1":
-      name: "jsonrpc"
-      ip: "127.0.0.1"
-      port: 20001
-
diff --git a/examples/jsonrpc/go-server/profiles/release/server.yml b/examples/jsonrpc/go-server/profiles/release/server.yml
deleted file mode 100644
index 213d31d53eb2523e2e132810c7435b3696581a31..0000000000000000000000000000000000000000
--- a/examples/jsonrpc/go-server/profiles/release/server.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-application_config:
-    organization : "ikurento.com"
-    name : "BDTService"
-    module : "dubbogo user-info server"
-    version : "0.0.1"
-    owner : "ZX"
-    environment : "release"
-
-registries :
-  "hangzhouzk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2181"
-    username: ""
-    password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
-
-
-services:
- "UserProvider":
-   # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-   registry: "hangzhouzk"
-   protocol : "jsonrpc"
-  # 相当于dubbo.xml中的interface
-   interface : "com.ikurento.user.UserProvider"
-   loadbalance: "random"
-   warmup: "100"
-   cluster: "failover"
-   methods:
-     - name: "GetUser"
-       retries: 1
-       loadbalance: "random"
-
-protocols:
-  #-   name: "dubbo"
-  #    ip : "127.0.0.1"
-  #    port : 20000
-  "jsonrpc1":
-      name: "jsonrpc"
-      ip: "127.0.0.1"
-      port: 20001
-
diff --git a/examples/jsonrpc/go-server/profiles/test/server.yml b/examples/jsonrpc/go-server/profiles/test/server.yml
deleted file mode 100644
index 9b6dcb0b5c4513cf12ec5a505be64be156593c94..0000000000000000000000000000000000000000
--- a/examples/jsonrpc/go-server/profiles/test/server.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-application_config:
-    organization : "ikurento.com"
-    name : "BDTService"
-    module : "dubbogo user-info server"
-    version : "0.0.1"
-    owner : "ZX"
-    environment : "test"
-
-registries :
-  "hangzhouzk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2181"
-    username: ""
-    password: ""
-  "shanghaizk":
-    protocol: "zookeeper"
-    timeout	: "3s"
-    address: "127.0.0.1:2182"
-    username: ""
-    password: ""
-
-
-services:
- "UserProvider":
-   # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-   registry: "hangzhouzk"
-   protocol : "jsonrpc"
-  # 相当于dubbo.xml中的interface
-   interface : "com.ikurento.user.UserProvider"
-   loadbalance: "random"
-   warmup: "100"
-   cluster: "failover"
-   methods:
-     - name: "GetUser"
-       retries: 1
-       loadbalance: "random"
-
-protocols:
-  #-   name: "dubbo"
-  #    ip : "127.0.0.1"
-  #    port : 20000
-  "jsonrpc1":
-      name: "jsonrpc"
-      ip: "127.0.0.1"
-      port: 20001
-
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
deleted file mode 100644
index ddf899aa10979d65f9c88bc0b79ccbb065812417..0000000000000000000000000000000000000000
--- a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// *****************************************************
-// DESC    : dubbo consumer
-// AUTHOR  : writtey by 包增辉(https://github.com/baozh)
-// VERSION : 1.0
-// LICENCE : Apache License 2.0
-// EMAIL   : alexstocks@foxmail.com
-// MOD     : 2016-10-19 17:03
-// FILE    : Consumer.java
-// ******************************************************
-
-package com.ikurento.user;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import com.alibaba.dubbo.rpc.service.EchoService;
-import java.util.List;
-
-public class Consumer {
-    //定义一个私有变量 (Spring中要求)
-    private UserProvider userProvider;
-
-    //Spring注入(Spring中要求)
-    public void setUserProvider(UserProvider u) {
-        this.userProvider = u;
-    }
-
-    private void benchmarkSayHello() {
-        for (int i = 0; i < Integer.MAX_VALUE; i ++) {
-            try {
-                // String hello = demoService.sayHello("world" + i);
-                // System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " + hello);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
-            // Thread.sleep(2000);
-        }
-    }
-
-    private void testGetUser() throws Exception {
-        try {
-            EchoService echoService = (EchoService)userProvider;
-            Object status = echoService.$echo("OK");
-            System.out.println("echo: "+status);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        try {
-            User user1 = userProvider.GetUser("A003");
-            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                    " UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
-                    + ", age:" + user1.getAge() + ", time:" + user1.getTime().toString());
-            User user2 = userProvider.GetUser0("A003","Moorse");
-            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                     " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
-                     + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
-            User user3 = userProvider.getUser(1);
-            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                     " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
-                     + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
-
-            userProvider.GetUser3();
-            System.out.println("GetUser3 succ");
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void testGetUsers() throws Exception {
-        try {
-            List<String> userIDList = new ArrayList<String>();
-            userIDList.add("A001");
-            userIDList.add("A002");
-            userIDList.add("A003");
-
-            List<User> userList = userProvider.GetUsers(userIDList);
-
-            for (int i = 0; i < userList.size(); i++) {
-                User user = userList.get(i);
-                System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
-                        " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString()
-                        + ", age:" + user.getAge() + ", time:" + user.getTime().toString());
-            }
-       } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    //启动consumer的入口函数(在配置文件中指定)
-    public void start() throws Exception {
-        testGetUser();
-        testGetUsers();
-//        Thread.sleep(120000);
-Thread.sleep(2000);
-    }
-}
diff --git a/filter/impl/active_filter.go b/filter/impl/active_filter.go
index 435bfe7488c520b14d770aea01b3c3baf4950056..d7dad74cf3f5ccadf39372335bc1efb22f497523 100644
--- a/filter/impl/active_filter.go
+++ b/filter/impl/active_filter.go
@@ -1,14 +1,19 @@
-// Licensed 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.
+/*
+ * 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.
+ */
 
 // @author yiji@apache.org
 package impl
diff --git a/filter/impl/echo_filter_test.go b/filter/impl/echo_filter_test.go
index e2752c85b24b5dbc8175cbd125ed771b412d1818..e2e592974701ad18c5b01e884485c022ee2320b8 100644
--- a/filter/impl/echo_filter_test.go
+++ b/filter/impl/echo_filter_test.go
@@ -34,11 +34,11 @@ import (
 func TestEchoFilter_Invoke(t *testing.T) {
 	filter := GetFilter()
 	result := filter.Invoke(protocol.NewBaseInvoker(common.URL{}),
-		invocation.NewRPCInvocationForProvider("$echo", []interface{}{"OK"}, nil))
+		invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, nil))
 	assert.Equal(t, "OK", result.Result())
 
 	result = filter.Invoke(protocol.NewBaseInvoker(common.URL{}),
-		invocation.NewRPCInvocationForProvider("MethodName", []interface{}{"OK"}, nil))
+		invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, nil))
 	assert.Nil(t, result.Error())
 	assert.Nil(t, result.Result())
 }
diff --git a/filter/impl/generic_filter.go b/filter/impl/generic_filter.go
new file mode 100644
index 0000000000000000000000000000000000000000..35aadb11a444bda56109e238b17267f71ec2606b
--- /dev/null
+++ b/filter/impl/generic_filter.go
@@ -0,0 +1,133 @@
+/*
+ * 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 (
+	"reflect"
+	"strings"
+)
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+)
+import (
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/filter"
+	"github.com/apache/dubbo-go/protocol"
+	invocation2 "github.com/apache/dubbo-go/protocol/invocation"
+)
+
+const (
+	GENERIC = "generic"
+)
+
+func init() {
+	extension.SetFilter(GENERIC, GetGenericFilter)
+}
+
+//  when do a generic invoke, struct need to be map
+
+type GenericFilter struct{}
+
+func (ef *GenericFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+	if invocation.MethodName() == constant.GENERIC && len(invocation.Arguments()) == 3 {
+		oldArguments := invocation.Arguments()
+		var newParams []hessian.Object
+		if oldParams, ok := oldArguments[2].([]interface{}); ok {
+			for i := range oldParams {
+				newParams = append(newParams, hessian.Object(struct2MapAll(oldParams[i])))
+			}
+		} else {
+			return invoker.Invoke(invocation)
+		}
+		newArguments := []interface{}{
+			oldArguments[0],
+			oldArguments[1],
+			newParams,
+		}
+		newInvocation := invocation2.NewRPCInvocation(invocation.MethodName(), newArguments, invocation.Attachments())
+		newInvocation.SetReply(invocation.Reply())
+		return invoker.Invoke(newInvocation)
+	}
+	return invoker.Invoke(invocation)
+}
+
+func (ef *GenericFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+	return result
+}
+
+func GetGenericFilter() filter.Filter {
+	return &GenericFilter{}
+}
+func struct2MapAll(obj interface{}) interface{} {
+	if obj == nil {
+		return obj
+	}
+	t := reflect.TypeOf(obj)
+	v := reflect.ValueOf(obj)
+	if t.Kind() == reflect.Struct {
+		result := make(map[string]interface{}, t.NumField())
+		for i := 0; i < t.NumField(); i++ {
+			if v.Field(i).Kind() == reflect.Struct || v.Field(i).Kind() == reflect.Slice || v.Field(i).Kind() == reflect.Map {
+				if v.Field(i).CanInterface() {
+					setInMap(result, t.Field(i), struct2MapAll(v.Field(i).Interface()))
+				}
+			} else {
+				if v.Field(i).CanInterface() {
+					setInMap(result, t.Field(i), v.Field(i).Interface())
+				}
+			}
+		}
+		return result
+	} else if t.Kind() == reflect.Slice {
+		value := reflect.ValueOf(obj)
+		var newTemps = make([]interface{}, 0, value.Len())
+		for i := 0; i < value.Len(); i++ {
+			newTemp := struct2MapAll(value.Index(i).Interface())
+			newTemps = append(newTemps, newTemp)
+		}
+		return newTemps
+	} else if t.Kind() == reflect.Map {
+		var newTempMap = make(map[string]interface{}, v.Len())
+		iter := v.MapRange()
+		for iter.Next() {
+			mapK := iter.Key().String()
+			if !iter.Value().CanInterface() {
+				continue
+			}
+			mapV := iter.Value().Interface()
+			newTempMap[mapK] = struct2MapAll(mapV)
+		}
+		return newTempMap
+	} else {
+		return obj
+	}
+}
+func setInMap(m map[string]interface{}, structField reflect.StructField, value interface{}) (result map[string]interface{}) {
+	result = m
+	if tagName := structField.Tag.Get("m"); tagName == "" {
+		result[headerAtoa(structField.Name)] = value
+	} else {
+		result[tagName] = value
+	}
+	return
+}
+func headerAtoa(a string) (b string) {
+	b = strings.ToLower(a[:1]) + a[1:]
+	return
+}
diff --git a/filter/impl/generic_filter_test.go b/filter/impl/generic_filter_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9797c40df1f57017241675013620a53320e475ad
--- /dev/null
+++ b/filter/impl/generic_filter_test.go
@@ -0,0 +1,121 @@
+/*
+ * 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 (
+	"reflect"
+	"testing"
+)
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_struct2MapAll(t *testing.T) {
+	var testData struct {
+		AaAa string `m:"aaAa"`
+		BaBa string
+		CaCa struct {
+			AaAa string
+			BaBa string `m:"baBa"`
+			XxYy struct {
+				xxXx string `m:"xxXx"`
+				Xx   string `m:"xx"`
+			} `m:"xxYy"`
+		} `m:"caCa"`
+	}
+	testData.AaAa = "1"
+	testData.BaBa = "1"
+	testData.CaCa.BaBa = "2"
+	testData.CaCa.AaAa = "2"
+	testData.CaCa.XxYy.xxXx = "3"
+	testData.CaCa.XxYy.Xx = "3"
+	m := struct2MapAll(testData).(map[string]interface{})
+	assert.Equal(t, "1", m["aaAa"].(string))
+	assert.Equal(t, "1", m["baBa"].(string))
+	assert.Equal(t, "2", m["caCa"].(map[string]interface{})["aaAa"].(string))
+	assert.Equal(t, "3", m["caCa"].(map[string]interface{})["xxYy"].(map[string]interface{})["xx"].(string))
+
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"].(map[string]interface{})["xxYy"]).Kind())
+}
+
+type testStruct struct {
+	AaAa string
+	BaBa string `m:"baBa"`
+	XxYy struct {
+		xxXx string `m:"xxXx"`
+		Xx   string `m:"xx"`
+	} `m:"xxYy"`
+}
+
+func Test_struct2MapAll_Slice(t *testing.T) {
+	var testData struct {
+		AaAa string `m:"aaAa"`
+		BaBa string
+		CaCa []testStruct `m:"caCa"`
+	}
+	testData.AaAa = "1"
+	testData.BaBa = "1"
+	var tmp testStruct
+	tmp.BaBa = "2"
+	tmp.AaAa = "2"
+	tmp.XxYy.xxXx = "3"
+	tmp.XxYy.Xx = "3"
+	testData.CaCa = append(testData.CaCa, tmp)
+	m := struct2MapAll(testData).(map[string]interface{})
+
+	assert.Equal(t, "1", m["aaAa"].(string))
+	assert.Equal(t, "1", m["baBa"].(string))
+	assert.Equal(t, "2", m["caCa"].([]interface{})[0].(map[string]interface{})["aaAa"].(string))
+	assert.Equal(t, "3", m["caCa"].([]interface{})[0].(map[string]interface{})["xxYy"].(map[string]interface{})["xx"].(string))
+
+	assert.Equal(t, reflect.Slice, reflect.TypeOf(m["caCa"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"].([]interface{})[0].(map[string]interface{})["xxYy"]).Kind())
+}
+func Test_struct2MapAll_Map(t *testing.T) {
+	var testData struct {
+		AaAa string
+		Baba map[string]interface{}
+		CaCa map[string]string
+		DdDd map[string]interface{}
+	}
+	testData.AaAa = "aaaa"
+	testData.Baba = make(map[string]interface{})
+	testData.CaCa = make(map[string]string)
+	testData.DdDd = nil
+
+	testData.Baba["kk"] = 1
+	var structData struct {
+		Str string
+	}
+	structData.Str = "str"
+	testData.Baba["struct"] = structData
+	testData.Baba["nil"] = nil
+	testData.CaCa["k1"] = "v1"
+	testData.CaCa["kv2"] = "v2"
+	m := struct2MapAll(testData)
+
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m).Kind())
+	assert.Equal(t, reflect.String, reflect.TypeOf(m.(map[string]interface{})["aaAa"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["baba"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["baba"].(map[string]interface{})["struct"]).Kind())
+	assert.Equal(t, "str", m.(map[string]interface{})["baba"].(map[string]interface{})["struct"].(map[string]interface{})["str"])
+	assert.Equal(t, nil, m.(map[string]interface{})["baba"].(map[string]interface{})["nil"])
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["caCa"]).Kind())
+	assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["ddDd"]).Kind())
+}
diff --git a/go.mod b/go.mod
index e1ab3c34bfb26e8fa8a81ee0e95d03a969a84be8..52785aa5f5cfbc8158a49c90a369d179a332f5f0 100644
--- a/go.mod
+++ b/go.mod
@@ -1,16 +1,49 @@
 module github.com/apache/dubbo-go
 
 require (
-	github.com/dubbogo/getty v1.0.7
+	github.com/Workiva/go-datastructures v1.0.50
+	github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect
+	github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190731020727-1697039810c8
+	github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
+	github.com/coreos/bbolt v1.3.3 // indirect
+	github.com/coreos/etcd v3.3.13+incompatible
+	github.com/coreos/go-semver v0.3.0 // indirect
+	github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
+	github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
+	github.com/dubbogo/getty v1.2.2
 	github.com/dubbogo/gost v1.1.1
-	github.com/dubbogo/hessian2 v1.2.0
+	github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
+	github.com/go-errors/errors v1.0.1 // indirect
+	github.com/gogo/protobuf v1.2.1 // indirect
+	github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect
+	github.com/golang/mock v1.3.1
+	github.com/google/btree v1.0.0 // indirect
+	github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
+	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
+	github.com/grpc-ecosystem/grpc-gateway v1.9.5 // indirect
+	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
 	github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8
+	github.com/jonboulle/clockwork v0.1.0 // indirect
+	github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
+	github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f // indirect
+	github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
 	github.com/magiconair/properties v1.8.1
+	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb
 	github.com/pkg/errors v0.8.1
+	github.com/prometheus/client_golang v1.1.0 // indirect
 	github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
+	github.com/soheilhy/cmux v0.1.4 // indirect
 	github.com/stretchr/testify v1.3.0
-	github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f
+	github.com/tebeka/strftime v0.1.3 // indirect
+	github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
+	github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect
+	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
+	go.etcd.io/bbolt v1.3.3 // indirect
+	go.etcd.io/etcd v3.3.13+incompatible
 	go.uber.org/atomic v1.4.0
 	go.uber.org/zap v1.10.0
+	google.golang.org/grpc v1.22.1
 	gopkg.in/yaml.v2 v2.2.2
 )
diff --git a/go.sum b/go.sum
index 745c68f1ecc255fd4c016e653581e7434e05bdfa..e70701ff96cccb0026edaa36135f3ed785863159 100644
--- a/go.sum
+++ b/go.sum
@@ -1,45 +1,232 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo=
+github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0=
+github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ=
+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.20190731020727-1697039810c8 h1:7zJlM+8bpCAUhv03TZnXkT4MLlLWng1s7An8CLuN73E=
+github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190731020727-1697039810c8/go.mod h1:LWnndnrFXZmJLAzoyNAPNHSIJ1KOHVkTSsHgC3YYWlo=
+github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI=
+github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
+github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dubbogo/getty v1.0.7 h1:5Hg+JwXyCKm9Yr4yJkm98ahhnoa8c2h6br5QJxwQ+YU=
-github.com/dubbogo/getty v1.0.7/go.mod h1:cRMSuoCmwc5lULFFnYZTxyCfZhObmRTNbS7XRnPNHSo=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dubbogo/getty v1.2.2 h1:qDC9WXjxcs5NPvWZz2ruVKBKr2r1Jjm6i0Sq//CQwbE=
+github.com/dubbogo/getty v1.2.2/go.mod h1:K4b3MkGLf7T+lMgQNFgpg0dI1Wvv1PTisFs1Psf86kU=
 github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI=
 github.com/dubbogo/gost v1.1.1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
-github.com/dubbogo/hessian2 v1.2.0 h1:5wFYuMzzRhneUAPbVBVKubIknrEjUM/B76vievYD0Vw=
-github.com/dubbogo/hessian2 v1.2.0/go.mod h1:7EohF3mE7xmZcj43nP172sapRHOEifcV/jwyHhG4SaY=
+github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
+github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
+github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:BWIsLfhgKhV5g/oF34aRjniBHLTZe5DNekSjbAjIS6c=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
+github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
 github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
 github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo=
+github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE=
+github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgUSP4zdTUZYZgAGGtN5Lxk92rK+JUFOwf+FT99EEI4=
+github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8=
+github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc=
+github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
 github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb h1:lbmvw8r9W55w+aQgWn35W1nuleRIECMoqUrmwAOAvoI=
+github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
+github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
+github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
+github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec h1:6ncX5ko6B9LntYM0YBRXkiSaZMmLYeZ/NWcmeB43mMY=
 github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f h1:QatZ4lsJBY3x1+Imst9g95+vUl7m52dqM9Pi4aSMW8w=
-github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f/go.mod h1:BNLmYJ8oMJPIPpNx5968jCyUhwEU1XT3YsuOqtbo5qo=
+github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto=
+github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk=
+github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3xbw=
+go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
 go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
+golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
+gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/protocol/RpcStatus.go b/protocol/RpcStatus.go
index b9f3e6ecb18583034e310471164773bebe689cd9..78796b6beaf24dac33d7e0210703a9027f9fe568 100644
--- a/protocol/RpcStatus.go
+++ b/protocol/RpcStatus.go
@@ -1,14 +1,19 @@
-// Licensed 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.
+/*
+ * 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.
+ */
 
 // @author yiji@apache.org
 package protocol
diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go
index 8ba46e7b0b321095652fb7c6d0c1c7403e1fea1e..6ac5e7215429338aa7cabb646b3afd3f1a136b68 100644
--- a/protocol/dubbo/client.go
+++ b/protocol/dubbo/client.go
@@ -24,8 +24,9 @@ import (
 )
 
 import (
+	"github.com/apache/dubbo-go-hessian2"
 	"github.com/dubbogo/getty"
-	"github.com/dubbogo/hessian2"
+	"github.com/dubbogo/gost/sync"
 	perrors "github.com/pkg/errors"
 	"go.uber.org/atomic"
 	"gopkg.in/yaml.v2"
@@ -45,7 +46,8 @@ var (
 	errClientClosed      = perrors.New("client closed")
 	errClientReadTimeout = perrors.New("client read timeout")
 
-	clientConf *ClientConfig
+	clientConf   *ClientConfig
+	clientGrpool *gxsync.TaskPool
 )
 
 func init() {
@@ -78,6 +80,7 @@ func init() {
 	}
 
 	clientConf = conf
+	setClientGrpool()
 }
 
 func SetClientConf(c ClientConfig) {
@@ -87,59 +90,29 @@ func SetClientConf(c ClientConfig) {
 		logger.Warnf("[ClientConfig CheckValidity] error: %v", err)
 		return
 	}
+	setClientGrpool()
 }
 
 func GetClientConf() ClientConfig {
 	return *clientConf
 }
 
-type CallOptions struct {
+func setClientGrpool() {
+	if clientConf.GrPoolSize > 1 {
+		clientGrpool = gxsync.NewTaskPool(gxsync.WithTaskPoolTaskPoolSize(clientConf.GrPoolSize), gxsync.WithTaskPoolTaskQueueLength(clientConf.QueueLen),
+			gxsync.WithTaskPoolTaskQueueNumber(clientConf.QueueNumber))
+	}
+}
+
+type Options struct {
+	// connect timeout
+	ConnectTimeout time.Duration
 	// request timeout
 	RequestTimeout time.Duration
-	// response timeout
-	ResponseTimeout time.Duration
-	// serial ID
-	SerialID SerialID
-	Meta     map[interface{}]interface{}
 }
 
-type CallOption func(*CallOptions)
-
-//func WithCallRequestTimeout(d time.Duration) CallOption {
-//	return func(o *CallOptions) {
-//		o.RequestTimeout = d
-//	}
-//}
-//
-//func WithCallResponseTimeout(d time.Duration) CallOption {
-//	return func(o *CallOptions) {
-//		o.ResponseTimeout = d
-//	}
-//}
-//
-//func WithCallSerialID(s SerialID) CallOption {
-//	return func(o *CallOptions) {
-//		o.SerialID = s
-//	}
-//}
-//
-//func WithCallMeta_All(callMeta map[interface{}]interface{}) CallOption {
-//	return func(o *CallOptions) {
-//		o.Meta = callMeta
-//	}
-//}
-
-//func WithCallMeta(k, v interface{}) CallOption {
-//	return func(o *CallOptions) {
-//		if o.Meta == nil {
-//			o.Meta = make(map[interface{}]interface{})
-//		}
-//		o.Meta[k] = v
-//	}
-//}
-
 type CallResponse struct {
-	Opts      CallOptions
+	Opts      Options
 	Cause     error
 	Start     time.Time // invoke(call) start time == write start time
 	ReadStart time.Time // read start time, write duration = ReadStart - Start
@@ -149,6 +122,7 @@ type CallResponse struct {
 type AsyncCallback func(response CallResponse)
 
 type Client struct {
+	opts     Options
 	conf     ClientConfig
 	pool     *gettyRPCClientPool
 	sequence atomic.Uint64
@@ -156,9 +130,18 @@ type Client struct {
 	pendingResponses *sync.Map
 }
 
-func NewClient() *Client {
+func NewClient(opt Options) *Client {
+
+	switch {
+	case opt.ConnectTimeout == 0:
+		opt.ConnectTimeout = 3e9
+		fallthrough
+	case opt.RequestTimeout == 0:
+		opt.RequestTimeout = 3e9
+	}
 
 	c := &Client{
+		opts:             opt,
 		pendingResponses: new(sync.Map),
 		conf:             *clientConf,
 	}
@@ -168,64 +151,38 @@ func NewClient() *Client {
 }
 
 // call one way
-func (c *Client) CallOneway(addr string, svcUrl common.URL, method string, args interface{}, opts ...CallOption) error {
-	var copts CallOptions
-
-	for _, o := range opts {
-		o(&copts)
-	}
+func (c *Client) CallOneway(addr string, svcUrl common.URL, method string, args interface{}) error {
 
-	return perrors.WithStack(c.call(CT_OneWay, addr, svcUrl, method, args, nil, nil, copts))
+	return perrors.WithStack(c.call(CT_OneWay, addr, svcUrl, method, args, nil, nil))
 }
 
 // if @reply is nil, the transport layer will get the response without notify the invoker.
-func (c *Client) Call(addr string, svcUrl common.URL, method string, args, reply interface{}, opts ...CallOption) error {
-	var copts CallOptions
-
-	for _, o := range opts {
-		o(&copts)
-	}
+func (c *Client) Call(addr string, svcUrl common.URL, method string, args, reply interface{}) error {
 
 	ct := CT_TwoWay
 	if reply == nil {
 		ct = CT_OneWay
 	}
 
-	return perrors.WithStack(c.call(ct, addr, svcUrl, method, args, reply, nil, copts))
+	return perrors.WithStack(c.call(ct, addr, svcUrl, method, args, reply, nil))
 }
 
 func (c *Client) AsyncCall(addr string, svcUrl common.URL, method string, args interface{},
-	callback AsyncCallback, reply interface{}, opts ...CallOption) error {
+	callback AsyncCallback, reply interface{}) error {
 
-	var copts CallOptions
-	for _, o := range opts {
-		o(&copts)
-	}
-
-	return perrors.WithStack(c.call(CT_TwoWay, addr, svcUrl, method, args, reply, callback, copts))
+	return perrors.WithStack(c.call(CT_TwoWay, addr, svcUrl, method, args, reply, callback))
 }
 
 func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string,
-	args, reply interface{}, callback AsyncCallback, opts CallOptions) error {
-
-	if opts.RequestTimeout == 0 {
-		opts.RequestTimeout = c.conf.GettySessionParam.tcpWriteTimeout
-	}
-	if opts.ResponseTimeout == 0 {
-		opts.ResponseTimeout = c.conf.GettySessionParam.tcpReadTimeout
-	}
+	args, reply interface{}, callback AsyncCallback) error {
 
 	p := &DubboPackage{}
 	p.Service.Path = strings.TrimPrefix(svcUrl.Path, "/")
 	p.Service.Interface = svcUrl.GetParam(constant.INTERFACE_KEY, "")
 	p.Service.Version = svcUrl.GetParam(constant.VERSION_KEY, "")
 	p.Service.Method = method
-	p.Service.Timeout = opts.RequestTimeout
-	if opts.SerialID == 0 {
-		p.Header.SerialID = byte(S_Dubbo)
-	} else {
-		p.Header.SerialID = byte(opts.SerialID)
-	}
+	p.Service.Timeout = c.opts.RequestTimeout
+	p.Header.SerialID = byte(S_Dubbo)
 	p.Body = args
 
 	var rsp *PendingResponse
@@ -234,7 +191,6 @@ func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string
 		rsp = NewPendingResponse()
 		rsp.reply = reply
 		rsp.callback = callback
-		rsp.opts = opts
 	} else {
 		p.Header.Type = hessian.PackageRequest
 	}
@@ -245,13 +201,15 @@ func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string
 		conn    *gettyRPCClient
 	)
 	conn, session, err = c.selectSession(addr)
-	if err != nil || session == nil {
-		logger.Warnf("%s, %v", errSessionNotExist.Error(), err)
+	if err != nil {
+		return perrors.WithStack(err)
+	}
+	if session == nil {
 		return errSessionNotExist
 	}
 	defer c.pool.release(conn, err)
 
-	if err = c.transfer(session, p, rsp, opts); err != nil {
+	if err = c.transfer(session, p, rsp); err != nil {
 		return perrors.WithStack(err)
 	}
 
@@ -260,7 +218,7 @@ func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string
 	}
 
 	select {
-	case <-time.After(opts.ResponseTimeout):
+	case <-getty.GetTimeWheel().After(c.opts.RequestTimeout):
 		err = errClientReadTimeout
 		c.removePendingResponse(SequenceType(rsp.seq))
 	case <-rsp.done:
@@ -286,11 +244,11 @@ func (c *Client) selectSession(addr string) (*gettyRPCClient, getty.Session, err
 }
 
 func (c *Client) heartbeat(session getty.Session) error {
-	return c.transfer(session, nil, NewPendingResponse(), CallOptions{})
+	return c.transfer(session, nil, NewPendingResponse())
 }
 
 func (c *Client) transfer(session getty.Session, pkg *DubboPackage,
-	rsp *PendingResponse, opts CallOptions) error {
+	rsp *PendingResponse) error {
 
 	var (
 		sequence uint64
@@ -313,7 +271,7 @@ func (c *Client) transfer(session getty.Session, pkg *DubboPackage,
 		c.addPendingResponse(rsp)
 	}
 
-	err = session.WritePkg(pkg, opts.RequestTimeout)
+	err = session.WritePkg(pkg, c.opts.RequestTimeout)
 	if err != nil {
 		c.removePendingResponse(SequenceType(rsp.seq))
 	} else if rsp != nil { // cond2
diff --git a/protocol/dubbo/client_test.go b/protocol/dubbo/client_test.go
index a39b0aef743d18c24f41b41655abfada996503e8..cd961d382933443e37a08c21b4e4de5edb971860 100644
--- a/protocol/dubbo/client_test.go
+++ b/protocol/dubbo/client_test.go
@@ -26,7 +26,7 @@ import (
 )
 
 import (
-	"github.com/dubbogo/hessian2"
+	hessian "github.com/apache/dubbo-go-hessian2"
 	perrors "github.com/pkg/errors"
 	"github.com/stretchr/testify/assert"
 )
@@ -42,6 +42,10 @@ func TestClient_CallOneway(t *testing.T) {
 	c := &Client{
 		pendingResponses: new(sync.Map),
 		conf:             *clientConf,
+		opts: Options{
+			ConnectTimeout: 3e9,
+			RequestTimeout: 6e9,
+		},
 	}
 	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
 
@@ -59,17 +63,21 @@ func TestClient_Call(t *testing.T) {
 	c := &Client{
 		pendingResponses: new(sync.Map),
 		conf:             *clientConf,
+		opts: Options{
+			ConnectTimeout: 3e9,
+			RequestTimeout: 10e9,
+		},
 	}
 	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
 
-	// user := &User{}
-	//err := c.Call("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, user)
-	//assert.NoError(t, err)
-	//assert.NotEqual(t, "", user.Id)
-	//assert.NotEqual(t, "", user.Name)
-
 	user := &User{}
-	err := c.Call("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, user)
+	err := c.Call("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, user)
+	assert.NoError(t, err)
+	assert.NotEqual(t, "", user.Id)
+	assert.NotEqual(t, "", user.Name)
+
+	user = &User{}
+	err = c.Call("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, user)
 	assert.NoError(t, err)
 	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
 
@@ -120,6 +128,10 @@ func TestClient_AsyncCall(t *testing.T) {
 	c := &Client{
 		pendingResponses: new(sync.Map),
 		conf:             *clientConf,
+		opts: Options{
+			ConnectTimeout: 3e9,
+			RequestTimeout: 6e9,
+		},
 	}
 	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
 
@@ -152,7 +164,6 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
 		ConnectionNum:   2,
 		HeartbeatPeriod: "5s",
 		SessionTimeout:  "20s",
-		FailFastTimeout: "5s",
 		PoolTTL:         600,
 		PoolSize:        64,
 		GettySessionParam: GettySessionParam{
@@ -162,7 +173,6 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
 			KeepAlivePeriod:  "120s",
 			TcpRBufSize:      262144,
 			TcpWBufSize:      65536,
-			PkgRQSize:        1024,
 			PkgWQSize:        512,
 			TcpReadTimeout:   "4s",
 			TcpWriteTimeout:  "5s",
@@ -173,9 +183,8 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
 	})
 	assert.NoError(t, clientConf.CheckValidity())
 	SetServerConfig(ServerConfig{
-		SessionNumber:   700,
-		SessionTimeout:  "20s",
-		FailFastTimeout: "5s",
+		SessionNumber:  700,
+		SessionTimeout: "20s",
 		GettySessionParam: GettySessionParam{
 			CompressEncoding: false,
 			TcpNoDelay:       true,
@@ -183,7 +192,6 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
 			KeepAlivePeriod:  "120s",
 			TcpRBufSize:      262144,
 			TcpWBufSize:      65536,
-			PkgRQSize:        1024,
 			PkgWQSize:        512,
 			TcpReadTimeout:   "1s",
 			TcpWriteTimeout:  "5s",
@@ -195,11 +203,11 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
 
 	// Export
 	proto := GetProtocol()
-	url, err := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+
+	url, err := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/UserProvider?anyhost=true&"+
 		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
 		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
 		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
-		"side=provider&timeout=3000&timestamp=1556509797245")
+		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
 	assert.NoError(t, err)
 	proto.Export(protocol.NewBaseInvoker(url))
 
@@ -274,12 +282,8 @@ func (u *UserProvider) GetUser6(id int64) (*User, error) {
 	return &User{Id: "1"}, nil
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
 }
 
 func (u User) JavaClassName() string {
diff --git a/protocol/dubbo/codec.go b/protocol/dubbo/codec.go
index cb57fc896f5e1c0be99a1e5978841ae17503064b..98c29a4e5bc576f7e37f74c0c0abbbab4687717b 100644
--- a/protocol/dubbo/codec.go
+++ b/protocol/dubbo/codec.go
@@ -25,7 +25,7 @@ import (
 )
 
 import (
-	"github.com/dubbogo/hessian2"
+	"github.com/apache/dubbo-go-hessian2"
 	perrors "github.com/pkg/errors"
 )
 
@@ -112,7 +112,6 @@ type PendingResponse struct {
 	readStart time.Time
 	callback  AsyncCallback
 	reply     interface{}
-	opts      CallOptions
 	done      chan struct{}
 }
 
@@ -125,7 +124,6 @@ func NewPendingResponse() *PendingResponse {
 
 func (r PendingResponse) GetCallResponse() CallResponse {
 	return CallResponse{
-		Opts:      r.opts,
 		Cause:     r.err,
 		Start:     r.start,
 		ReadStart: r.readStart,
diff --git a/protocol/dubbo/codec_test.go b/protocol/dubbo/codec_test.go
index 4f5229d67242e582a128caa40c205482e813f08e..52bb1fc130bb2dad866799f01c43d11ffd10a220 100644
--- a/protocol/dubbo/codec_test.go
+++ b/protocol/dubbo/codec_test.go
@@ -20,10 +20,11 @@ package dubbo
 import (
 	"testing"
 	"time"
+)
 
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
 	"github.com/stretchr/testify/assert"
-
-	hessian "github.com/dubbogo/hessian2"
 )
 
 func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) {
@@ -49,6 +50,7 @@ func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) {
 	// request
 	pkg.Header.Type = hessian.PackageRequest
 	pkg.Service.Interface = "Service"
+	pkg.Service.Path = "path"
 	pkg.Service.Version = "2.6"
 	pkg.Service.Method = "Method"
 	pkg.Service.Timeout = time.Second
@@ -63,10 +65,10 @@ func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) {
 	assert.Equal(t, byte(S_Dubbo), pkgres.Header.SerialID)
 	assert.Equal(t, int64(10086), pkgres.Header.ID)
 	assert.Equal(t, "2.5.4", pkgres.Body.([]interface{})[0])
-	assert.Equal(t, "", pkgres.Body.([]interface{})[1])
+	assert.Equal(t, "path", pkgres.Body.([]interface{})[1])
 	assert.Equal(t, "2.6", pkgres.Body.([]interface{})[2])
 	assert.Equal(t, "Method", pkgres.Body.([]interface{})[3])
 	assert.Equal(t, "Ljava/lang/String;", pkgres.Body.([]interface{})[4])
 	assert.Equal(t, []interface{}{"a"}, pkgres.Body.([]interface{})[5])
-	assert.Equal(t, map[interface{}]interface{}{"interface": "Service", "path": "", "group": "", "timeout": "1000"}, pkgres.Body.([]interface{})[6])
+	assert.Equal(t, map[interface{}]interface{}{"group": "", "interface": "Service", "path": "path", "timeout": "1000"}, pkgres.Body.([]interface{})[6])
 }
diff --git a/protocol/dubbo/config.go b/protocol/dubbo/config.go
index 0af1a4a41116fca06d6793fddaf7f69ade2f30c0..1ac3c9ad97ec34319c7728555e56cdfb3d038ba7 100644
--- a/protocol/dubbo/config.go
+++ b/protocol/dubbo/config.go
@@ -34,7 +34,6 @@ type (
 		keepAlivePeriod  time.Duration
 		TcpRBufSize      int    `default:"262144" yaml:"tcp_r_buf_size" json:"tcp_r_buf_size,omitempty"`
 		TcpWBufSize      int    `default:"65536" yaml:"tcp_w_buf_size" json:"tcp_w_buf_size,omitempty"`
-		PkgRQSize        int    `default:"1024" yaml:"pkg_rq_size" json:"pkg_rq_size,omitempty"`
 		PkgWQSize        int    `default:"1024" yaml:"pkg_wq_size" json:"pkg_wq_size,omitempty"`
 		TcpReadTimeout   string `default:"1s" yaml:"tcp_read_timeout" json:"tcp_read_timeout,omitempty"`
 		tcpReadTimeout   time.Duration
@@ -48,20 +47,15 @@ type (
 
 	// Config holds supported types by the multiconfig package
 	ServerConfig struct {
-		// local address
-		//AppName     string   `default:"rpc-server" yaml:"app_name" json:"app_name,omitempty"`
-		//Host        string   `default:"127.0.0.1" yaml:"host" json:"host,omitempty"`
-		//Ports       []string `yaml:"ports" json:"ports,omitempty"` // `default:["10000"]`
-		//ProfilePort int      `default:"10086" yaml:"profile_port" json:"profile_port,omitempty"`
-
 		// session
 		SessionTimeout string `default:"60s" yaml:"session_timeout" json:"session_timeout,omitempty"`
 		sessionTimeout time.Duration
 		SessionNumber  int `default:"1000" yaml:"session_number" json:"session_number,omitempty"`
 
-		// app
-		FailFastTimeout string `default:"5s" yaml:"fail_fast_timeout" json:"fail_fast_timeout,omitempty"`
-		failFastTimeout time.Duration
+		// grpool
+		GrPoolSize  int `default:"0" yaml:"gr_pool_size" json:"gr_pool_size,omitempty"`
+		QueueLen    int `default:"0" yaml:"queue_len" json:"queue_len,omitempty"`
+		QueueNumber int `default:"0" yaml:"queue_number" json:"queue_number,omitempty"`
 
 		// session tcp parameters
 		GettySessionParam GettySessionParam `required:"true" yaml:"getty_session_param" json:"getty_session_param,omitempty"`
@@ -69,11 +63,6 @@ type (
 
 	// Config holds supported types by the multiconfig package
 	ClientConfig struct {
-		// local address
-		//AppName     string `default:"rpc-client" yaml:"app_name" json:"app_name,omitempty"`
-		//Host        string `default:"127.0.0.1" yaml:"host" json:"host,omitempty"`
-		//ProfilePort int    `default:"10086" yaml:"profile_port" json:"profile_port,omitempty"`
-
 		ReconnectInterval int `default:"0" yaml:"reconnect_interval" json:"reconnect_interval,omitempty"`
 
 		// session pool
@@ -87,14 +76,15 @@ type (
 		SessionTimeout string `default:"60s" yaml:"session_timeout" json:"session_timeout,omitempty"`
 		sessionTimeout time.Duration
 
-		// app
-		FailFastTimeout string `default:"5s" yaml:"fail_fast_timeout" json:"fail_fast_timeout,omitempty"`
-		failFastTimeout time.Duration
-
 		// Connection Pool
 		PoolSize int `default:"2" yaml:"pool_size" json:"pool_size,omitempty"`
 		PoolTTL  int `default:"180" yaml:"pool_ttl" json:"pool_ttl,omitempty"`
 
+		// grpool
+		GrPoolSize  int `default:"0" yaml:"gr_pool_size" json:"gr_pool_size,omitempty"`
+		QueueLen    int `default:"0" yaml:"queue_len" json:"queue_len,omitempty"`
+		QueueNumber int `default:"0" yaml:"queue_number" json:"queue_number,omitempty"`
+
 		// session tcp parameters
 		GettySessionParam GettySessionParam `required:"true" yaml:"getty_session_param" json:"getty_session_param,omitempty"`
 	}
@@ -125,6 +115,8 @@ func (c *GettySessionParam) CheckValidity() error {
 func (c *ClientConfig) CheckValidity() error {
 	var err error
 
+	c.ReconnectInterval = c.ReconnectInterval * 1e6
+
 	if c.heartbeatPeriod, err = time.ParseDuration(c.HeartbeatPeriod); err != nil {
 		return perrors.WithMessagef(err, "time.ParseDuration(HeartbeatPeroid{%#v})", c.HeartbeatPeriod)
 	}
@@ -133,10 +125,6 @@ func (c *ClientConfig) CheckValidity() error {
 		return perrors.WithMessagef(err, "time.ParseDuration(SessionTimeout{%#v})", c.SessionTimeout)
 	}
 
-	if c.failFastTimeout, err = time.ParseDuration(c.FailFastTimeout); err != nil {
-		return perrors.WithMessagef(err, "time.ParseDuration(FailFastTimeout{%#v})", c.FailFastTimeout)
-	}
-
 	return perrors.WithStack(c.GettySessionParam.CheckValidity())
 }
 
@@ -147,9 +135,5 @@ func (c *ServerConfig) CheckValidity() error {
 		return perrors.WithMessagef(err, "time.ParseDuration(SessionTimeout{%#v})", c.SessionTimeout)
 	}
 
-	if c.failFastTimeout, err = time.ParseDuration(c.FailFastTimeout); err != nil {
-		return perrors.WithMessagef(err, "time.ParseDuration(FailFastTimeout{%#v})", c.FailFastTimeout)
-	}
-
 	return perrors.WithStack(c.GettySessionParam.CheckValidity())
 }
diff --git a/protocol/dubbo/dubbo_exporter.go b/protocol/dubbo/dubbo_exporter.go
index bdec8a349f358f265fe064ed2083433f27d40a3b..cb06b6b69c9d0873342af5ea49fae054f029608c 100644
--- a/protocol/dubbo/dubbo_exporter.go
+++ b/protocol/dubbo/dubbo_exporter.go
@@ -39,9 +39,9 @@ func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap *sync.Ma
 }
 
 func (de *DubboExporter) Unexport() {
-	service := de.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")
+	serviceId := de.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "")
 	de.BaseExporter.Unexport()
-	err := common.ServiceMap.UnRegister(DUBBO, service)
+	err := common.ServiceMap.UnRegister(DUBBO, serviceId)
 	if err != nil {
 		logger.Errorf("[DubboExporter.Unexport] error: %v", err)
 	}
diff --git a/protocol/dubbo/dubbo_invoker_test.go b/protocol/dubbo/dubbo_invoker_test.go
index 182d6d8e0b11cfcb231789cebf9c4cefdecfa258..09a4c128b600e605de616a65027da9b2ce6fcb20 100644
--- a/protocol/dubbo/dubbo_invoker_test.go
+++ b/protocol/dubbo/dubbo_invoker_test.go
@@ -38,13 +38,18 @@ func TestDubboInvoker_Invoke(t *testing.T) {
 	c := &Client{
 		pendingResponses: new(sync.Map),
 		conf:             *clientConf,
+		opts: Options{
+			ConnectTimeout: 3e9,
+			RequestTimeout: 6e9,
+		},
 	}
 	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
 
 	invoker := NewDubboInvoker(url, c)
 	user := &User{}
 
-	inv := invocation.NewRPCInvocationForConsumer("GetUser", nil, []interface{}{"1", "username"}, user, nil, url, nil)
+	inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("GetUser"), invocation.WithArguments([]interface{}{"1", "username"}),
+		invocation.WithReply(user))
 
 	// Call
 	res := invoker.Invoke(inv)
diff --git a/protocol/dubbo/dubbo_protocol.go b/protocol/dubbo/dubbo_protocol.go
index a2df3d91b2fa6b1ef8907ecba8832368d0613b8e..4438a0b3d0e32127536b818806d190a2d2a5a2ba 100644
--- a/protocol/dubbo/dubbo_protocol.go
+++ b/protocol/dubbo/dubbo_protocol.go
@@ -21,6 +21,7 @@ import (
 	"github.com/apache/dubbo-go/common"
 	"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/protocol"
 	"sync"
 )
@@ -63,7 +64,10 @@ func (dp *DubboProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
 }
 
 func (dp *DubboProtocol) Refer(url common.URL) protocol.Invoker {
-	invoker := NewDubboInvoker(url, NewClient())
+	invoker := NewDubboInvoker(url, NewClient(Options{
+		ConnectTimeout: config.GetConsumerConfig().ConnectTimeout,
+		RequestTimeout: config.GetConsumerConfig().RequestTimeout,
+	}))
 	dp.SetInvokers(invoker)
 	logger.Infof("Refer service: %s", url.String())
 	return invoker
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
index 55ee929301e4e62e6b868c5b85b9952fc354b723..aa208284825665dae4c23f871117a7f34c548d16 100644
--- a/protocol/dubbo/listener.go
+++ b/protocol/dubbo/listener.go
@@ -27,8 +27,8 @@ import (
 )
 
 import (
+	"github.com/apache/dubbo-go-hessian2"
 	"github.com/dubbogo/getty"
-	"github.com/dubbogo/hessian2"
 	perrors "github.com/pkg/errors"
 )
 
@@ -91,6 +91,7 @@ func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) {
 		if p.Err != nil {
 			logger.Errorf("rpc heartbeat response{error: %#v}", p.Err)
 		}
+		h.conn.pool.rpcClient.removePendingResponse(SequenceType(p.Header.ID))
 		return
 	}
 	logger.Debugf("get rpc response{header: %#v, body: %#v}", p.Header, p.Body)
@@ -208,12 +209,8 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) {
 		twoway = false
 	}
 
-	group := p.Body.(map[string]interface{})["attachments"].(map[interface{}]interface{})[constant.GROUP_KEY]
-	if group == nil {
-		group = ""
-	}
 	u := common.NewURLWithOptions(common.WithPath(p.Service.Path), common.WithParams(url.Values{}),
-		common.WithParamsValue(constant.GROUP_KEY, group.(string)),
+		common.WithParamsValue(constant.GROUP_KEY, p.Service.Group),
 		common.WithParamsValue(constant.INTERFACE_KEY, p.Service.Interface),
 		common.WithParamsValue(constant.VERSION_KEY, p.Service.Version))
 	exporter, _ := dubboProtocol.ExporterMap().Load(u.ServiceKey())
@@ -227,9 +224,9 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) {
 	}
 	invoker := exporter.(protocol.Exporter).GetInvoker()
 	if invoker != nil {
-		result := invoker.Invoke(invocation.NewRPCInvocationForProvider(p.Service.Method, p.Body.(map[string]interface{})["args"].([]interface{}), map[string]string{
+		result := invoker.Invoke(invocation.NewRPCInvocation(p.Service.Method, p.Body.(map[string]interface{})["args"].([]interface{}), map[string]string{
 			constant.PATH_KEY:      p.Service.Path,
-			constant.GROUP_KEY:     group.(string),
+			constant.GROUP_KEY:     p.Service.Group,
 			constant.INTERFACE_KEY: p.Service.Interface,
 			constant.VERSION_KEY:   p.Service.Version,
 		}))
diff --git a/protocol/dubbo/pool.go b/protocol/dubbo/pool.go
index de205fa75f5fe8e8ef75c7c0f12cc2f78b3c397b..546a5b335aee3e71a6e00e49888710edb20c694a 100644
--- a/protocol/dubbo/pool.go
+++ b/protocol/dubbo/pool.go
@@ -62,16 +62,18 @@ func newGettyRPCClientConn(pool *gettyRPCClientPool, protocol, addr string) (*ge
 			getty.WithReconnectInterval(pool.rpcClient.conf.ReconnectInterval),
 		),
 	}
-	c.gettyClient.RunEventLoop(c.newSession)
+	go c.gettyClient.RunEventLoop(c.newSession)
 	idx := 1
+	times := int(pool.rpcClient.opts.ConnectTimeout / 1e6)
 	for {
 		idx++
 		if c.isAvailable() {
 			break
 		}
 
-		if idx > 5000 {
-			return nil, perrors.New(fmt.Sprintf("failed to create client connection to %s in 5 seconds", addr))
+		if idx > times {
+			c.gettyClient.Close()
+			return nil, perrors.New(fmt.Sprintf("failed to create client connection to %s in %f seconds", addr, float32(times)/1000))
 		}
 		time.Sleep(1e6)
 	}
@@ -109,7 +111,6 @@ func (c *gettyRPCClient) newSession(session getty.Session) error {
 	session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
 	session.SetPkgHandler(NewRpcClientPackageHandler(c.pool.rpcClient))
 	session.SetEventListener(NewRpcClientHandler(c))
-	session.SetRQLen(conf.GettySessionParam.PkgRQSize)
 	session.SetWQLen(conf.GettySessionParam.PkgWQSize)
 	session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout)
 	session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout)
@@ -117,6 +118,8 @@ func (c *gettyRPCClient) newSession(session getty.Session) error {
 	session.SetWaitTime(conf.GettySessionParam.waitTimeout)
 	logger.Debugf("client new session:%s\n", session.Stat())
 
+	session.SetTaskPool(clientGrpool)
+
 	return nil
 }
 
@@ -166,7 +169,9 @@ func (c *gettyRPCClient) removeSession(session getty.Session) {
 	}
 	logger.Infof("after remove session{%s}, left session number:%d", session.Stat(), len(c.sessions))
 	if len(c.sessions) == 0 {
+		c.pool.Lock()
 		c.close() // -> pool.remove(c)
+		c.pool.Unlock()
 	}
 }
 
@@ -193,8 +198,8 @@ func (c *gettyRPCClient) getClientRpcSession(session getty.Session) (rpcSession,
 		err        error
 		rpcSession rpcSession
 	)
-	c.lock.Lock()
-	defer c.lock.Unlock()
+	c.lock.RLock()
+	defer c.lock.RUnlock()
 	if c.sessions == nil {
 		return rpcSession, errClientClosed
 	}
@@ -241,11 +246,11 @@ func (c *gettyRPCClient) close() error {
 
 type gettyRPCClientPool struct {
 	rpcClient *Client
-	size      int   // []*gettyRPCClient数组的size
-	ttl       int64 // 每个gettyRPCClient的有效期时间. pool对象会在getConn时执行ttl检查
+	size      int   // size of []*gettyRPCClient
+	ttl       int64 // ttl of every gettyRPCClient, it is checked when getConn
 
 	sync.Mutex
-	conns []*gettyRPCClient // 从[]*gettyRPCClient 可见key是连接地址,而value是对应这个地址的连接数组
+	conns []*gettyRPCClient
 }
 
 func newGettyRPCClientConnPool(rpcClient *Client, size int, ttl time.Duration) *gettyRPCClientPool {
@@ -270,7 +275,6 @@ func (p *gettyRPCClientPool) close() {
 func (p *gettyRPCClientPool) getGettyRpcClient(protocol, addr string) (*gettyRPCClient, error) {
 
 	p.Lock()
-	defer p.Unlock()
 	if p.conns == nil {
 		return nil, errClientPoolClosed
 	}
@@ -287,10 +291,11 @@ func (p *gettyRPCClientPool) getGettyRpcClient(protocol, addr string) (*gettyRPC
 		}
 		conn.created = now //update created time
 
+		p.Unlock()
 		return conn, nil
 	}
-
 	// create new conn
+	p.Unlock()
 	return newGettyRPCClientConn(p, protocol, addr)
 }
 
diff --git a/protocol/dubbo/readwriter.go b/protocol/dubbo/readwriter.go
index 042b8789104d1e671807405a81045dc30adcf789..8c6c8a5a53af4df9a89eae5db5752eb07f3aa446 100644
--- a/protocol/dubbo/readwriter.go
+++ b/protocol/dubbo/readwriter.go
@@ -23,10 +23,11 @@ import (
 )
 
 import (
+	hessian "github.com/apache/dubbo-go-hessian2"
 	"github.com/dubbogo/getty"
-	hessian "github.com/dubbogo/hessian2"
 	perrors "github.com/pkg/errors"
 )
+
 import (
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/constant"
@@ -140,11 +141,17 @@ func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface
 				attachments = req[6].(map[interface{}]interface{})
 			}
 			pkg.Service.Interface = attachments[constant.INTERFACE_KEY].(string)
+			if pkg.Service.Path == "" && attachments[constant.PATH_KEY] != nil {
+				pkg.Service.Path = attachments[constant.PATH_KEY].(string)
+			}
+			if attachments[constant.GROUP_KEY] != nil {
+				pkg.Service.Group = attachments[constant.GROUP_KEY].(string)
+			}
 			pkg.Body = map[string]interface{}{
 				"dubboVersion": dubboVersion,
 				"argsTypes":    argsTypes,
 				"args":         args,
-				"service":      common.ServiceMap.GetService(DUBBO, pkg.Service.Interface),
+				"service":      common.ServiceMap.GetService(DUBBO, pkg.Service.Path), // path as a key
 				"attachments":  attachments,
 			}
 		}
diff --git a/protocol/dubbo/server.go b/protocol/dubbo/server.go
index 25c8f1bf4d7deaf87c3216cbfcd70d499ed2fb24..8daeee05e2ccc115aad590c2ed80a269360482d5 100644
--- a/protocol/dubbo/server.go
+++ b/protocol/dubbo/server.go
@@ -24,6 +24,7 @@ import (
 
 import (
 	"github.com/dubbogo/getty"
+	"github.com/dubbogo/gost/sync"
 	"gopkg.in/yaml.v2"
 )
 
@@ -33,7 +34,10 @@ import (
 	"github.com/apache/dubbo-go/config"
 )
 
-var srvConf *ServerConfig
+var (
+	srvConf   *ServerConfig
+	srvGrpool *gxsync.TaskPool
+)
 
 func init() {
 
@@ -64,6 +68,7 @@ func init() {
 	}
 
 	srvConf = conf
+	SetServerGrpool()
 }
 
 func SetServerConfig(s ServerConfig) {
@@ -73,12 +78,20 @@ func SetServerConfig(s ServerConfig) {
 		logger.Warnf("[ServerConfig CheckValidity] error: %v", err)
 		return
 	}
+	SetServerGrpool()
 }
 
 func GetServerConfig() ServerConfig {
 	return *srvConf
 }
 
+func SetServerGrpool() {
+	if srvConf.GrPoolSize > 1 {
+		srvGrpool = gxsync.NewTaskPool(gxsync.WithTaskPoolTaskPoolSize(srvConf.GrPoolSize), gxsync.WithTaskPoolTaskQueueLength(srvConf.QueueLen),
+			gxsync.WithTaskPoolTaskQueueNumber(srvConf.QueueNumber))
+	}
+}
+
 type Server struct {
 	conf       ServerConfig
 	tcpServer  getty.Server
@@ -123,7 +136,6 @@ func (s *Server) newSession(session getty.Session) error {
 	session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
 	session.SetPkgHandler(rpcServerPkgHandler)
 	session.SetEventListener(s.rpcHandler)
-	session.SetRQLen(conf.GettySessionParam.PkgRQSize)
 	session.SetWQLen(conf.GettySessionParam.PkgWQSize)
 	session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout)
 	session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout)
@@ -131,6 +143,8 @@ func (s *Server) newSession(session getty.Session) error {
 	session.SetWaitTime(conf.GettySessionParam.waitTimeout)
 	logger.Debugf("app accepts new session:%s\n", session.Stat())
 
+	session.SetTaskPool(srvGrpool)
+
 	return nil
 }
 
diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go
index d515cc4c8ad4bcdcc88eccd4b1e8ddb545a17315..2124a22f1611b24d7f4370de64b117c58c4f7e7b 100644
--- a/protocol/invocation/rpcinvocation.go
+++ b/protocol/invocation/rpcinvocation.go
@@ -22,8 +22,6 @@ import (
 )
 
 import (
-	"github.com/apache/dubbo-go/common"
-	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/protocol"
 )
 
@@ -41,27 +39,7 @@ type RPCInvocation struct {
 	invoker        protocol.Invoker
 }
 
-func NewRPCInvocationForConsumer(methodName string, parameterTypes []reflect.Type, arguments []interface{},
-	reply interface{}, callBack interface{}, url common.URL, invoker protocol.Invoker) *RPCInvocation {
-
-	attachments := map[string]string{}
-	attachments[constant.PATH_KEY] = url.Path
-	attachments[constant.GROUP_KEY] = url.GetParam(constant.GROUP_KEY, "")
-	attachments[constant.INTERFACE_KEY] = url.GetParam(constant.INTERFACE_KEY, "")
-	attachments[constant.VERSION_KEY] = url.GetParam(constant.VERSION_KEY, "")
-
-	return &RPCInvocation{
-		methodName:     methodName,
-		parameterTypes: parameterTypes,
-		arguments:      arguments,
-		reply:          reply,
-		callBack:       callBack,
-		attachments:    attachments,
-		invoker:        invoker,
-	}
-}
-
-func NewRPCInvocationForProvider(methodName string, arguments []interface{}, attachments map[string]string) *RPCInvocation {
+func NewRPCInvocation(methodName string, arguments []interface{}, attachments map[string]string) *RPCInvocation {
 	return &RPCInvocation{
 		methodName:  methodName,
 		arguments:   arguments,
@@ -69,26 +47,6 @@ func NewRPCInvocationForProvider(methodName string, arguments []interface{}, att
 	}
 }
 
-type option func(invo *RPCInvocation)
-
-func WithMethodName(methodName string) option {
-	return func(invo *RPCInvocation) {
-		invo.methodName = methodName
-	}
-}
-
-func WithParameterTypes(parameterTypes []reflect.Type) option {
-	return func(invo *RPCInvocation) {
-		invo.parameterTypes = parameterTypes
-	}
-}
-
-func WithArguments(arguments []interface{}) option {
-	return func(invo *RPCInvocation) {
-		invo.arguments = arguments
-	}
-}
-
 func NewRPCInvocationWithOptions(opts ...option) *RPCInvocation {
 	invo := &RPCInvocation{}
 	for _, opt := range opts {
@@ -147,14 +105,58 @@ func (r *RPCInvocation) SetInvoker() protocol.Invoker {
 	return r.invoker
 }
 
+func (r *RPCInvocation) CallBack() interface{} {
+	return r.callBack
+}
+
 func (r *RPCInvocation) SetCallBack(c interface{}) {
 	r.callBack = c
 }
 
-func (r *RPCInvocation) CallBack() interface{} {
-	return r.callBack
+///////////////////////////
+// option
+///////////////////////////
+
+type option func(invo *RPCInvocation)
+
+func WithMethodName(methodName string) option {
+	return func(invo *RPCInvocation) {
+		invo.methodName = methodName
+	}
+}
+
+func WithParameterTypes(parameterTypes []reflect.Type) option {
+	return func(invo *RPCInvocation) {
+		invo.parameterTypes = parameterTypes
+	}
+}
+
+func WithArguments(arguments []interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.arguments = arguments
+	}
+}
+
+func WithReply(reply interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.reply = reply
+	}
+}
+
+func WithCallBack(callBack interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.callBack = callBack
+	}
+}
+
+func WithAttachments(attachments map[string]string) option {
+	return func(invo *RPCInvocation) {
+		invo.attachments = attachments
+	}
 }
 
-func (r *RPCInvocation) SetMethod(method string) {
-	r.methodName = method
+func WithInvoker(invoker protocol.Invoker) option {
+	return func(invo *RPCInvocation) {
+		invo.invoker = invoker
+	}
 }
diff --git a/protocol/invoker.go b/protocol/invoker.go
index fe6aab848caceed50fc3db3e657ce87c45eac2ed..f5d41a09ad2778c12c7e5e68167a4d0acc9e3f4c 100644
--- a/protocol/invoker.go
+++ b/protocol/invoker.go
@@ -22,6 +22,7 @@ import (
 	"github.com/apache/dubbo-go/common/logger"
 )
 
+//go:generate mockgen -source invoker.go -destination mock/mock_invoker.go  -self_package github.com/apache/dubbo-go/protocol/mock --package mock  Invoker
 // Extension - Invoker
 type Invoker interface {
 	common.Node
diff --git a/protocol/jsonrpc/http_test.go b/protocol/jsonrpc/http_test.go
index f05f47b8c1b571846335852503bb2c3a5a8c5a8d..1f446803fd6c5f174f51e3fe9496c49ae4991691 100644
--- a/protocol/jsonrpc/http_test.go
+++ b/protocol/jsonrpc/http_test.go
@@ -54,11 +54,11 @@ func TestHTTPClient_Call(t *testing.T) {
 
 	// Export
 	proto := GetProtocol()
-	url, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&"+
+	url, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/UserProvider?anyhost=true&"+
 		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
 		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
 		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
-		"side=provider&timeout=3000&timestamp=1556509797245")
+		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
 	assert.NoError(t, err)
 	proto.Export(protocol.NewBaseInvoker(url))
 	time.Sleep(time.Second * 2)
@@ -185,10 +185,6 @@ func (u *UserProvider) GetUser4(id float64) (*User, error) {
 	return &User{Id: "1"}, nil
 }
 
-func (u *UserProvider) Service() string {
-	return "com.ikurento.user.UserProvider"
-}
-
-func (u *UserProvider) Version() string {
-	return ""
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
 }
diff --git a/protocol/jsonrpc/jsonrpc_exporter.go b/protocol/jsonrpc/jsonrpc_exporter.go
index 21a2465cddde7709bf5a23f6247ecb74016bf129..6720330494a3b833d4a67d8b2408377ce62b1ddf 100644
--- a/protocol/jsonrpc/jsonrpc_exporter.go
+++ b/protocol/jsonrpc/jsonrpc_exporter.go
@@ -39,9 +39,9 @@ func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.
 }
 
 func (je *JsonrpcExporter) Unexport() {
-	service := je.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")
+	serviceId := je.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "")
 	je.BaseExporter.Unexport()
-	err := common.ServiceMap.UnRegister(JSONRPC, service)
+	err := common.ServiceMap.UnRegister(JSONRPC, serviceId)
 	if err != nil {
 		logger.Errorf("[JsonrpcExporter.Unexport] error: %v", err)
 	}
diff --git a/protocol/jsonrpc/jsonrpc_invoker_test.go b/protocol/jsonrpc/jsonrpc_invoker_test.go
index 0dd427eb69127317d646c599506dc476f2859a3f..bc88759bf522a35a30e8585429f1db614c3a15ce 100644
--- a/protocol/jsonrpc/jsonrpc_invoker_test.go
+++ b/protocol/jsonrpc/jsonrpc_invoker_test.go
@@ -41,11 +41,11 @@ func TestJsonrpcInvoker_Invoke(t *testing.T) {
 
 	// Export
 	proto := GetProtocol()
-	url, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&"+
+	url, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/UserProvider?anyhost=true&"+
 		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
 		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
 		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
-		"side=provider&timeout=3000&timestamp=1556509797245")
+		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
 	assert.NoError(t, err)
 	proto.Export(protocol.NewBaseInvoker(url))
 	time.Sleep(time.Second * 2)
@@ -57,7 +57,9 @@ func TestJsonrpcInvoker_Invoke(t *testing.T) {
 
 	jsonInvoker := NewJsonrpcInvoker(url, client)
 	user := &User{}
-	res := jsonInvoker.Invoke(invocation.NewRPCInvocationForConsumer("GetUser", nil, []interface{}{"1", "username"}, user, nil, url, nil))
+	res := jsonInvoker.Invoke(invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("GetUser"), invocation.WithArguments([]interface{}{"1", "username"}),
+		invocation.WithReply(user)))
+
 	assert.NoError(t, res.Error())
 	assert.Equal(t, User{Id: "1", Name: "username"}, *res.Result().(*User))
 
diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go
index 22dc7cfc49c978a7c042652158210ef6fda48892..6b3a39c68b4fdb417e8d2efaec4a43806acb2219 100644
--- a/protocol/jsonrpc/server.go
+++ b/protocol/jsonrpc/server.go
@@ -325,7 +325,7 @@ func serveRequest(ctx context.Context,
 	exporter, _ := jsonrpcProtocol.ExporterMap().Load(path)
 	invoker := exporter.(*JsonrpcExporter).GetInvoker()
 	if invoker != nil {
-		result := invoker.Invoke(invocation.NewRPCInvocationForProvider(methodName, args, map[string]string{
+		result := invoker.Invoke(invocation.NewRPCInvocation(methodName, args, map[string]string{
 			constant.PATH_KEY:    path,
 			constant.VERSION_KEY: codec.req.Version,
 		}))
@@ -348,15 +348,14 @@ func serveRequest(ctx context.Context,
 			}
 		}
 	}
-	serviceName := invoker.GetUrl().Service()
 	// get method
-	svc := common.ServiceMap.GetService(JSONRPC, serviceName)
+	svc := common.ServiceMap.GetService(JSONRPC, path)
 	if svc == nil {
-		return perrors.New("cannot find svc " + serviceName)
+		return perrors.New("cannot find svc " + path)
 	}
 	method := svc.Method()[methodName]
 	if method == nil {
-		return perrors.New("cannot find method " + methodName + " of svc " + serviceName)
+		return perrors.New("cannot find method " + methodName + " of svc " + path)
 	}
 
 	in := []reflect.Value{svc.Rcvr()}
diff --git a/protocol/mock/mock_invoker.go b/protocol/mock/mock_invoker.go
new file mode 100644
index 0000000000000000000000000000000000000000..557dafa277e95c39d0b960436ac10ba8842c9186
--- /dev/null
+++ b/protocol/mock/mock_invoker.go
@@ -0,0 +1,87 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: invoker.go
+
+// Package mock is a generated GoMock package.
+package mock
+
+import (
+	"reflect"
+)
+
+import (
+	"github.com/golang/mock/gomock"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/protocol"
+)
+
+// MockInvoker is a mock of Invoker interface
+type MockInvoker struct {
+	ctrl     *gomock.Controller
+	recorder *MockInvokerMockRecorder
+}
+
+// MockInvokerMockRecorder is the mock recorder for MockInvoker
+type MockInvokerMockRecorder struct {
+	mock *MockInvoker
+}
+
+// NewMockInvoker creates a new mock instance
+func NewMockInvoker(ctrl *gomock.Controller) *MockInvoker {
+	mock := &MockInvoker{ctrl: ctrl}
+	mock.recorder = &MockInvokerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use
+func (m *MockInvoker) EXPECT() *MockInvokerMockRecorder {
+	return m.recorder
+}
+
+// GetUrl mocks base method
+func (m *MockInvoker) GetUrl() common.URL {
+	ret := m.ctrl.Call(m, "GetUrl")
+	ret0, _ := ret[0].(common.URL)
+	return ret0
+}
+
+// GetUrl indicates an expected call of GetUrl
+func (mr *MockInvokerMockRecorder) GetUrl() *gomock.Call {
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUrl", reflect.TypeOf((*MockInvoker)(nil).GetUrl))
+}
+
+// IsAvailable mocks base method
+func (m *MockInvoker) IsAvailable() bool {
+	ret := m.ctrl.Call(m, "IsAvailable")
+	ret0, _ := ret[0].(bool)
+	return ret0
+}
+
+// IsAvailable indicates an expected call of IsAvailable
+func (mr *MockInvokerMockRecorder) IsAvailable() *gomock.Call {
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsAvailable", reflect.TypeOf((*MockInvoker)(nil).IsAvailable))
+}
+
+// Destroy mocks base method
+func (m *MockInvoker) Destroy() {
+	m.ctrl.Call(m, "Destroy")
+}
+
+// Destroy indicates an expected call of Destroy
+func (mr *MockInvokerMockRecorder) Destroy() *gomock.Call {
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Destroy", reflect.TypeOf((*MockInvoker)(nil).Destroy))
+}
+
+// Invoke mocks base method
+func (m *MockInvoker) Invoke(arg0 protocol.Invocation) protocol.Result {
+	ret := m.ctrl.Call(m, "Invoke", arg0)
+	ret0, _ := ret[0].(protocol.Result)
+	return ret0
+}
+
+// Invoke indicates an expected call of Invoke
+func (mr *MockInvokerMockRecorder) Invoke(arg0 interface{}) *gomock.Call {
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Invoke", reflect.TypeOf((*MockInvoker)(nil).Invoke), arg0)
+}
diff --git a/registry/etcdv3/listener.go b/registry/etcdv3/listener.go
new file mode 100644
index 0000000000000000000000000000000000000000..a8f2facc1aa43db4daea77c03f332df16f302431
--- /dev/null
+++ b/registry/etcdv3/listener.go
@@ -0,0 +1,88 @@
+package etcdv3
+
+import (
+	"context"
+	"strings"
+)
+
+import (
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/registry"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+type dataListener struct {
+	interestedURL []*common.URL
+	listener      remoting.ConfigurationListener
+}
+
+func NewRegistryDataListener(listener remoting.ConfigurationListener) *dataListener {
+	return &dataListener{listener: listener, interestedURL: []*common.URL{}}
+}
+
+func (l *dataListener) AddInterestedURL(url *common.URL) {
+	l.interestedURL = append(l.interestedURL, url)
+}
+
+func (l *dataListener) DataChange(eventType remoting.Event) bool {
+
+	url := eventType.Path[strings.Index(eventType.Path, "/providers/")+len("/providers/"):]
+	serviceURL, err := common.NewURL(context.Background(), url)
+	if err != nil {
+		logger.Warnf("Listen NewURL(r{%s}) = error{%v}", eventType.Path, err)
+		return false
+	}
+
+	for _, v := range l.interestedURL {
+		if serviceURL.URLEqual(*v) {
+			l.listener.Process(&remoting.ConfigChangeEvent{Key: eventType.Path, Value: serviceURL, ConfigType: eventType.Action})
+			return true
+		}
+	}
+
+	return false
+}
+
+type configurationListener struct {
+	registry *etcdV3Registry
+	events   chan *remoting.ConfigChangeEvent
+}
+
+func NewConfigurationListener(reg *etcdV3Registry) *configurationListener {
+	// add a new waiter
+	reg.wg.Add(1)
+	return &configurationListener{registry: reg, events: make(chan *remoting.ConfigChangeEvent, 32)}
+}
+func (l *configurationListener) Process(configType *remoting.ConfigChangeEvent) {
+	l.events <- configType
+}
+
+func (l *configurationListener) Next() (*registry.ServiceEvent, error) {
+	for {
+		select {
+		case <-l.registry.done:
+			logger.Warnf("listener's etcd client connection is broken, so etcd event listener exit now.")
+			return nil, perrors.New("listener stopped")
+
+		case e := <-l.events:
+			logger.Infof("got etcd event %#v", e)
+			if e.ConfigType == remoting.EventTypeDel {
+				select {
+				case <-l.registry.done:
+					logger.Warnf("update @result{%s}. But its connection to registry is invalid", e.Value)
+				default:
+				}
+				continue
+			}
+			return &registry.ServiceEvent{Action: e.ConfigType, Service: e.Value.(common.URL)}, nil
+		}
+	}
+}
+func (l *configurationListener) Close() {
+	l.registry.wg.Done()
+}
diff --git a/registry/etcdv3/listener_test.go b/registry/etcdv3/listener_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..0ac8fc475e454e737e0ea03301709457561e961c
--- /dev/null
+++ b/registry/etcdv3/listener_test.go
@@ -0,0 +1,71 @@
+package etcdv3
+
+import (
+	"context"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/dubbogo/getty"
+	"github.com/stretchr/testify/suite"
+	"go.etcd.io/etcd/embed"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+type RegistryTestSuite struct {
+	suite.Suite
+	etcd *embed.Etcd
+}
+
+// start etcd server
+func (suite *RegistryTestSuite) SetupSuite() {
+
+	t := suite.T()
+
+	cfg := embed.NewConfig()
+	cfg.Dir = "/tmp/default.etcd"
+	e, err := embed.StartEtcd(cfg)
+	if err != nil {
+		t.Fatal(err)
+	}
+	select {
+	case <-e.Server.ReadyNotify():
+		t.Log("Server is ready!")
+	case <-getty.GetTimeWheel().After(60 * time.Second):
+		e.Server.Stop() // trigger a shutdown
+		t.Logf("Server took too long to start!")
+	}
+
+	suite.etcd = e
+	return
+}
+
+// stop etcd server
+func (suite *RegistryTestSuite) TearDownSuite() {
+	suite.etcd.Close()
+}
+
+func (suite *RegistryTestSuite) TestDataChange() {
+
+	t := suite.T()
+
+	listener := NewRegistryDataListener(&MockDataListener{})
+	url, _ := common.NewURL(context.Background(), "jsonrpc%3A%2F%2F127.0.0.1%3A20001%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26app.version%3D0.0.1%26application%3DBDTService%26category%3Dproviders%26cluster%3Dfailover%26dubbo%3Ddubbo-provider-golang-2.6.0%26environment%3Ddev%26group%3D%26interface%3Dcom.ikurento.user.UserProvider%26ip%3D10.32.20.124%26loadbalance%3Drandom%26methods.GetUser.loadbalance%3Drandom%26methods.GetUser.retries%3D1%26methods.GetUser.weight%3D0%26module%3Ddubbogo%2Buser-info%2Bserver%26name%3DBDTService%26organization%3Dikurento.com%26owner%3DZX%26pid%3D74500%26retries%3D0%26service.filter%3Decho%26side%3Dprovider%26timestamp%3D1560155407%26version%3D%26warmup%3D100")
+	listener.AddInterestedURL(&url)
+	if !listener.DataChange(remoting.Event{Path: "/dubbo/com.ikurento.user.UserProvider/providers/jsonrpc%3A%2F%2F127.0.0.1%3A20001%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26app.version%3D0.0.1%26application%3DBDTService%26category%3Dproviders%26cluster%3Dfailover%26dubbo%3Ddubbo-provider-golang-2.6.0%26environment%3Ddev%26group%3D%26interface%3Dcom.ikurento.user.UserProvider%26ip%3D10.32.20.124%26loadbalance%3Drandom%26methods.GetUser.loadbalance%3Drandom%26methods.GetUser.retries%3D1%26methods.GetUser.weight%3D0%26module%3Ddubbogo%2Buser-info%2Bserver%26name%3DBDTService%26organization%3Dikurento.com%26owner%3DZX%26pid%3D74500%26retries%3D0%26service.filter%3Decho%26side%3Dprovider%26timestamp%3D1560155407%26version%3D%26warmup%3D100"}) {
+		t.Fatal("data change not ok")
+	}
+}
+
+func TestRegistrySuite(t *testing.T) {
+	suite.Run(t, &RegistryTestSuite{})
+}
+
+type MockDataListener struct{}
+
+func (*MockDataListener) Process(configType *remoting.ConfigChangeEvent) {}
diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go
new file mode 100644
index 0000000000000000000000000000000000000000..5802142989e5d8297f027ddecff3d7780070729f
--- /dev/null
+++ b/registry/etcdv3/registry.go
@@ -0,0 +1,325 @@
+package etcdv3
+
+import (
+	"fmt"
+	"net/url"
+	"os"
+	"path"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+import (
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/common/utils"
+	"github.com/apache/dubbo-go/registry"
+	"github.com/apache/dubbo-go/remoting/etcdv3"
+)
+
+var (
+	processID = ""
+	localIP   = ""
+)
+
+const Name = "etcdv3"
+
+func init() {
+	processID = fmt.Sprintf("%d", os.Getpid())
+	localIP, _ = utils.GetLocalIP()
+	extension.SetRegistry(Name, newETCDV3Registry)
+}
+
+type etcdV3Registry struct {
+	*common.URL
+	birth int64 // time of file birth, seconds since Epoch; 0 if unknown
+
+	cltLock  sync.Mutex
+	client   *etcdv3.Client
+	services map[string]common.URL // service name + protocol -> service config
+
+	listenerLock   sync.Mutex
+	listener       *etcdv3.EventListener
+	dataListener   *dataListener
+	configListener *configurationListener
+
+	wg   sync.WaitGroup // wg+done for etcd client restart
+	done chan struct{}
+}
+
+func (r *etcdV3Registry) Client() *etcdv3.Client {
+	return r.client
+}
+func (r *etcdV3Registry) SetClient(client *etcdv3.Client) {
+	r.client = client
+}
+func (r *etcdV3Registry) ClientLock() *sync.Mutex {
+	return &r.cltLock
+}
+func (r *etcdV3Registry) WaitGroup() *sync.WaitGroup {
+	return &r.wg
+}
+func (r *etcdV3Registry) GetDone() chan struct{} {
+	return r.done
+}
+func (r *etcdV3Registry) RestartCallBack() bool {
+
+	services := []common.URL{}
+	for _, confIf := range r.services {
+		services = append(services, confIf)
+	}
+
+	flag := true
+	for _, confIf := range services {
+		err := r.Register(confIf)
+		if err != nil {
+			logger.Errorf("(etcdV3ProviderRegistry)register(conf{%#v}) = error{%#v}",
+				confIf, perrors.WithStack(err))
+			flag = false
+			break
+		}
+		logger.Infof("success to re-register service :%v", confIf.Key())
+	}
+	return flag
+}
+
+func newETCDV3Registry(url *common.URL) (registry.Registry, error) {
+
+	timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT))
+	if err != nil {
+		logger.Errorf("timeout config %v is invalid ,err is %v",
+			url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT), err.Error())
+		return nil, perrors.WithMessagef(err, "new etcd registry(address:%+v)", url.Location)
+	}
+
+	logger.Infof("etcd address is: %v, timeout is: %s", url.Location, timeout.String())
+
+	r := &etcdV3Registry{
+		URL:      url,
+		birth:    time.Now().UnixNano(),
+		done:     make(chan struct{}),
+		services: make(map[string]common.URL),
+	}
+
+	if err := etcdv3.ValidateClient(
+		r,
+		etcdv3.WithName(etcdv3.RegistryETCDV3Client),
+		etcdv3.WithTimeout(timeout),
+		etcdv3.WithEndpoints(url.Location),
+	); err != nil {
+		return nil, err
+	}
+
+	r.wg.Add(1)
+	go etcdv3.HandleClientRestart(r)
+
+	r.listener = etcdv3.NewEventListener(r.client)
+	r.configListener = NewConfigurationListener(r)
+	r.dataListener = NewRegistryDataListener(r.configListener)
+
+	return r, nil
+}
+
+func (r *etcdV3Registry) GetUrl() common.URL {
+	return *r.URL
+}
+
+func (r *etcdV3Registry) IsAvailable() bool {
+
+	select {
+	case <-r.done:
+		return false
+	default:
+		return true
+	}
+}
+
+func (r *etcdV3Registry) Destroy() {
+
+	if r.configListener != nil {
+		r.configListener.Close()
+	}
+	r.stop()
+}
+
+func (r *etcdV3Registry) stop() {
+
+	close(r.done)
+
+	// close current client
+	r.client.Close()
+
+	r.cltLock.Lock()
+	r.client = nil
+	r.services = nil
+	r.cltLock.Unlock()
+}
+
+func (r *etcdV3Registry) Register(svc common.URL) error {
+
+	role, err := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, ""))
+	if err != nil {
+		return perrors.WithMessage(err, "get registry role")
+	}
+
+	r.cltLock.Lock()
+	if _, ok := r.services[svc.Key()]; ok {
+		r.cltLock.Unlock()
+		return perrors.New(fmt.Sprintf("Path{%s} has been registered", svc.Path))
+	}
+	r.cltLock.Unlock()
+
+	switch role {
+	case common.PROVIDER:
+		logger.Debugf("(provider register )Register(conf{%#v})", svc)
+		if err := r.registerProvider(svc); err != nil {
+			return perrors.WithMessage(err, "register provider")
+		}
+	case common.CONSUMER:
+		logger.Debugf("(consumer register )Register(conf{%#v})", svc)
+		if err := r.registerConsumer(svc); err != nil {
+			return perrors.WithMessage(err, "register consumer")
+		}
+	default:
+		return perrors.New(fmt.Sprintf("unknown role %d", role))
+	}
+
+	r.cltLock.Lock()
+	r.services[svc.Key()] = svc
+	r.cltLock.Unlock()
+	return nil
+}
+
+func (r *etcdV3Registry) createDirIfNotExist(k string) error {
+
+	var tmpPath string
+	for _, str := range strings.Split(k, "/")[1:] {
+		tmpPath = path.Join(tmpPath, "/", str)
+		if err := r.client.Create(tmpPath, ""); err != nil {
+			return perrors.WithMessagef(err, "create path %s in etcd", tmpPath)
+		}
+	}
+
+	return nil
+}
+
+func (r *etcdV3Registry) registerConsumer(svc common.URL) error {
+
+	consumersNode := fmt.Sprintf("/dubbo/%s/%s", svc.Service(), common.DubboNodes[common.CONSUMER])
+	if err := r.createDirIfNotExist(consumersNode); err != nil {
+		logger.Errorf("etcd client create path %s: %v", consumersNode, err)
+		return perrors.WithMessage(err, "etcd create consumer nodes")
+	}
+	providersNode := fmt.Sprintf("/dubbo/%s/%s", svc.Service(), common.DubboNodes[common.PROVIDER])
+	if err := r.createDirIfNotExist(providersNode); err != nil {
+		return perrors.WithMessage(err, "create provider node")
+	}
+
+	params := url.Values{}
+
+	params.Add("protocol", svc.Protocol)
+
+	params.Add("category", (common.RoleType(common.CONSUMER)).String())
+	params.Add("dubbo", "dubbogo-consumer-"+constant.Version)
+
+	encodedURL := url.QueryEscape(fmt.Sprintf("consumer://%s%s?%s", localIP, svc.Path, params.Encode()))
+	dubboPath := fmt.Sprintf("/dubbo/%s/%s", svc.Service(), (common.RoleType(common.CONSUMER)).String())
+	if err := r.client.Create(path.Join(dubboPath, encodedURL), ""); err != nil {
+		return perrors.WithMessagef(err, "create k/v in etcd (path:%s, url:%s)", dubboPath, encodedURL)
+	}
+
+	return nil
+}
+
+func (r *etcdV3Registry) registerProvider(svc common.URL) error {
+
+	if len(svc.Path) == 0 || len(svc.Methods) == 0 {
+		return perrors.New(fmt.Sprintf("service path %s or service method %s", svc.Path, svc.Methods))
+	}
+
+	var (
+		urlPath    string
+		encodedURL string
+		dubboPath  string
+	)
+
+	providersNode := fmt.Sprintf("/dubbo/%s/%s", svc.Service(), common.DubboNodes[common.PROVIDER])
+	if err := r.createDirIfNotExist(providersNode); err != nil {
+		return perrors.WithMessage(err, "create provider node")
+	}
+
+	params := url.Values{}
+	for k, v := range svc.Params {
+		params[k] = v
+	}
+
+	params.Add("pid", processID)
+	params.Add("ip", localIP)
+	params.Add("anyhost", "true")
+	params.Add("category", (common.RoleType(common.PROVIDER)).String())
+	params.Add("dubbo", "dubbo-provider-golang-"+constant.Version)
+	params.Add("side", (common.RoleType(common.PROVIDER)).Role())
+
+	if len(svc.Methods) == 0 {
+		params.Add("methods", strings.Join(svc.Methods, ","))
+	}
+
+	logger.Debugf("provider url params:%#v", params)
+	var host string
+	if len(svc.Ip) == 0 {
+		host = localIP + ":" + svc.Port
+	} else {
+		host = svc.Ip + ":" + svc.Port
+	}
+
+	urlPath = svc.Path
+
+	encodedURL = url.QueryEscape(fmt.Sprintf("%s://%s%s?%s", svc.Protocol, host, urlPath, params.Encode()))
+	dubboPath = fmt.Sprintf("/dubbo/%s/%s", svc.Service(), (common.RoleType(common.PROVIDER)).String())
+
+	if err := r.client.Create(path.Join(dubboPath, encodedURL), ""); err != nil {
+		return perrors.WithMessagef(err, "create k/v in etcd (path:%s, url:%s)", dubboPath, encodedURL)
+	}
+
+	return nil
+}
+
+func (r *etcdV3Registry) Subscribe(svc common.URL) (registry.Listener, error) {
+
+	var (
+		configListener *configurationListener
+	)
+
+	r.listenerLock.Lock()
+	configListener = r.configListener
+	r.listenerLock.Unlock()
+	if r.listener == nil {
+		r.cltLock.Lock()
+		client := r.client
+		r.cltLock.Unlock()
+		if client == nil {
+			return nil, perrors.New("etcd client broken")
+		}
+
+		// new client & listener
+		listener := etcdv3.NewEventListener(r.client)
+
+		r.listenerLock.Lock()
+		r.listener = listener
+		r.listenerLock.Unlock()
+	}
+
+	//register the svc to dataListener
+	r.dataListener.AddInterestedURL(&svc)
+	go r.listener.ListenServiceEvent(fmt.Sprintf("/dubbo/%s/providers", svc.Service()), r.dataListener)
+
+	return configListener, nil
+}
diff --git a/registry/etcdv3/registry_test.go b/registry/etcdv3/registry_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..26204c74ad4305278e33d9c8b50199cfa578bf8a
--- /dev/null
+++ b/registry/etcdv3/registry_test.go
@@ -0,0 +1,112 @@
+package etcdv3
+
+import (
+	"context"
+	"strconv"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+)
+
+func initRegistry(t *testing.T) *etcdV3Registry {
+
+	regurl, err := common.NewURL(context.Background(), "registry://127.0.0.1:2379", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	reg, err := newETCDV3Registry(&regurl)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	out := reg.(*etcdV3Registry)
+	out.client.CleanKV()
+	return out
+}
+
+func (suite *RegistryTestSuite) TestRegister() {
+
+	t := suite.T()
+
+	url, _ := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"}))
+
+	reg := initRegistry(t)
+	err := reg.Register(url)
+	children, _, err := reg.client.GetChildrenKVList("/dubbo/com.ikurento.user.UserProvider/providers")
+	if err != nil {
+		t.Fatal(err)
+	}
+	assert.Regexp(t, ".*dubbo%3A%2F%2F127.0.0.1%3A20000%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26category%3Dproviders%26cluster%3Dmock%26dubbo%3Ddubbo-provider-golang-2.6.0%26.*provider", children)
+	assert.NoError(t, err)
+}
+
+func (suite *RegistryTestSuite) TestSubscribe() {
+
+	t := suite.T()
+	regurl, _ := common.NewURL(context.Background(), "registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)))
+	url, _ := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"}))
+
+	reg := initRegistry(t)
+	//provider register
+	err := reg.Register(url)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	//consumer register
+	regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+	reg2 := initRegistry(t)
+
+	reg2.Register(url)
+	listener, err := reg2.Subscribe(url)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	serviceEvent, err := listener.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	assert.Regexp(t, ".*ServiceEvent{Action{add}.*", serviceEvent.String())
+}
+
+func (suite *RegistryTestSuite) TestConsumerDestory() {
+
+	t := suite.T()
+	url, _ := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"}))
+
+	reg := initRegistry(t)
+	_, err := reg.Subscribe(url)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	//listener.Close()
+	time.Sleep(1e9)
+	reg.Destroy()
+
+	assert.Equal(t, false, reg.IsAvailable())
+
+}
+
+func (suite *RegistryTestSuite) TestProviderDestory() {
+
+	t := suite.T()
+	reg := initRegistry(t)
+	url, _ := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"}))
+	reg.Register(url)
+
+	//listener.Close()
+	time.Sleep(1e9)
+	reg.Destroy()
+	assert.Equal(t, false, reg.IsAvailable())
+}
diff --git a/registry/nacos/listener.go b/registry/nacos/listener.go
new file mode 100644
index 0000000000000000000000000000000000000000..c42abd0bb16573da33c20c150896f85b3a7edfd0
--- /dev/null
+++ b/registry/nacos/listener.go
@@ -0,0 +1,199 @@
+package nacos
+
+import (
+	"bytes"
+	"net/url"
+	"reflect"
+	"strconv"
+	"sync"
+)
+
+import (
+	"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
+	"github.com/nacos-group/nacos-sdk-go/model"
+	"github.com/nacos-group/nacos-sdk-go/vo"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/registry"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+type nacosListener struct {
+	namingClient   naming_client.INamingClient
+	listenUrl      common.URL
+	events         chan *remoting.ConfigChangeEvent
+	instanceMap    map[string]model.Instance
+	cacheLock      sync.Mutex
+	done           chan struct{}
+	subscribeParam *vo.SubscribeParam
+}
+
+func NewNacosListener(url common.URL, namingClient naming_client.INamingClient) (*nacosListener, error) {
+	listener := &nacosListener{
+		namingClient: namingClient,
+		listenUrl:    url, events: make(chan *remoting.ConfigChangeEvent, 32),
+		instanceMap: map[string]model.Instance{},
+		done:        make(chan struct{}),
+	}
+	err := listener.startListen()
+	return listener, err
+}
+
+func generateInstance(ss model.SubscribeService) model.Instance {
+	return model.Instance{
+		InstanceId:  ss.InstanceId,
+		Ip:          ss.Ip,
+		Port:        ss.Port,
+		ServiceName: ss.ServiceName,
+		Valid:       ss.Valid,
+		Enable:      ss.Enable,
+		Weight:      ss.Weight,
+		Metadata:    ss.Metadata,
+		ClusterName: ss.ClusterName,
+	}
+}
+
+func generateUrl(instance model.Instance) *common.URL {
+	if instance.Metadata == nil {
+		logger.Errorf("nacos instance metadata is empty,instance:%+v", instance)
+		return nil
+	}
+	path := instance.Metadata["path"]
+	myInterface := instance.Metadata["interface"]
+	if len(path) == 0 && len(myInterface) == 0 {
+		logger.Errorf("nacos instance metadata does not have  both path key and interface key,instance:%+v", instance)
+		return nil
+	}
+	if len(path) == 0 && len(myInterface) != 0 {
+		path = "/" + myInterface
+	}
+	protocol := instance.Metadata["protocol"]
+	if len(protocol) == 0 {
+		logger.Errorf("nacos instance metadata does not have protocol key,instance:%+v", instance)
+		return nil
+	}
+	urlMap := url.Values{}
+	for k, v := range instance.Metadata {
+		urlMap.Set(k, v)
+	}
+	return common.NewURLWithOptions(
+		common.WithIp(instance.Ip),
+		common.WithPort(strconv.Itoa(int(instance.Port))),
+		common.WithProtocol(protocol),
+		common.WithParams(urlMap),
+		common.WithPath(path),
+	)
+}
+
+func (nl *nacosListener) Callback(services []model.SubscribeService, err error) {
+	if err != nil {
+		logger.Errorf("nacos subscribe callback error:%s , subscribe:%+v ", err.Error(), nl.subscribeParam)
+		return
+	}
+	nl.cacheLock.Lock()
+	defer nl.cacheLock.Unlock()
+	addInstances := make([]model.Instance, 0, len(services))
+	delInstances := make([]model.Instance, 0, len(services))
+	updateInstances := make([]model.Instance, 0, len(services))
+
+	newInstanceMap := make(map[string]model.Instance, len(services))
+
+	for i := range services {
+		if !services[i].Enable || !services[i].Valid {
+			// instance is not available,so ignore it
+			continue
+		}
+		host := services[i].Ip + ":" + strconv.Itoa(int(services[i].Port))
+		instance := generateInstance(services[i])
+		newInstanceMap[host] = instance
+		if old, ok := nl.instanceMap[host]; !ok {
+			//instance is not exsit in cache,add it to cache
+			addInstances = append(addInstances, instance)
+		} else {
+			//instance is not different from cache,update it to cache
+			if !reflect.DeepEqual(old, instance) {
+				updateInstances = append(updateInstances, instance)
+			}
+		}
+	}
+
+	for host, inst := range nl.instanceMap {
+		if _, ok := newInstanceMap[host]; !ok {
+			//cache  instance is not exsit in  new instance list, remove it from  cache
+			delInstances = append(delInstances, inst)
+		}
+	}
+
+	nl.instanceMap = newInstanceMap
+
+	for i := range addInstances {
+		newUrl := generateUrl(addInstances[i])
+		if newUrl != nil {
+			nl.process(&remoting.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeAdd})
+		}
+	}
+	for i := range delInstances {
+		newUrl := generateUrl(delInstances[i])
+		if newUrl != nil {
+			nl.process(&remoting.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeDel})
+		}
+	}
+
+	for i := range updateInstances {
+		newUrl := generateUrl(updateInstances[i])
+		if newUrl != nil {
+			nl.process(&remoting.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EvnetTypeUpdate})
+		}
+	}
+}
+
+func getSubscribeName(url common.URL) string {
+	var buffer bytes.Buffer
+
+	buffer.Write([]byte(common.DubboNodes[common.PROVIDER]))
+	appendParam(&buffer, url, constant.INTERFACE_KEY)
+	appendParam(&buffer, url, constant.VERSION_KEY)
+	appendParam(&buffer, url, constant.GROUP_KEY)
+	return buffer.String()
+}
+
+func (nl *nacosListener) startListen() error {
+	if nl.namingClient == nil {
+		return perrors.New("nacos naming client stopped")
+	}
+	serviceName := getSubscribeName(nl.listenUrl)
+	nl.subscribeParam = &vo.SubscribeParam{ServiceName: serviceName, SubscribeCallback: nl.Callback}
+	return nl.namingClient.Subscribe(nl.subscribeParam)
+}
+
+func (nl *nacosListener) stopListen() error {
+	return nl.namingClient.Unsubscribe(nl.subscribeParam)
+}
+
+func (nl *nacosListener) process(configType *remoting.ConfigChangeEvent) {
+	nl.events <- configType
+}
+
+func (nl *nacosListener) Next() (*registry.ServiceEvent, error) {
+	for {
+		select {
+		case <-nl.done:
+			logger.Warnf("nacos listener is close!listenUrl:%+v", nl.listenUrl)
+			return nil, perrors.New("listener stopped")
+
+		case e := <-nl.events:
+			logger.Debugf("got nacos event %s", e)
+			return &registry.ServiceEvent{Action: e.ConfigType, Service: e.Value.(common.URL)}, nil
+		}
+	}
+}
+
+func (nl *nacosListener) Close() {
+	nl.stopListen()
+	close(nl.done)
+}
diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go
new file mode 100644
index 0000000000000000000000000000000000000000..f10e230bc44dba8f8007ea659db3747a237c9de1
--- /dev/null
+++ b/registry/nacos/registry.go
@@ -0,0 +1,176 @@
+package nacos
+
+import (
+	"bytes"
+	"net"
+	"strconv"
+	"strings"
+	"time"
+)
+import (
+	"github.com/nacos-group/nacos-sdk-go/clients"
+	"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
+	nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant"
+	"github.com/nacos-group/nacos-sdk-go/vo"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/utils"
+	"github.com/apache/dubbo-go/registry"
+)
+
+var (
+	localIP = ""
+)
+
+func init() {
+	localIP, _ = utils.GetLocalIP()
+	extension.SetRegistry(constant.NACOS_KEY, newNacosRegistry)
+}
+
+type nacosRegistry struct {
+	*common.URL
+	namingClient naming_client.INamingClient
+}
+
+func getNacosConfig(url *common.URL) (map[string]interface{}, error) {
+	if url == nil {
+		return nil, perrors.New("url is empty!")
+	}
+	if len(url.Location) == 0 {
+		return nil, perrors.New("url.location is empty!")
+	}
+	configMap := make(map[string]interface{}, 2)
+
+	addresses := strings.Split(url.Location, ",")
+	serverConfigs := make([]nacosConstant.ServerConfig, 0, len(addresses))
+	for _, addr := range addresses {
+		ip, portStr, err := net.SplitHostPort(addr)
+		if err != nil {
+			return nil, perrors.WithMessagef(err, "split [%s] ", addr)
+		}
+		port, _ := strconv.Atoi(portStr)
+		serverConfigs = append(serverConfigs, nacosConstant.ServerConfig{
+			IpAddr: ip,
+			Port:   uint64(port),
+		})
+	}
+	configMap["serverConfigs"] = serverConfigs
+
+	var clientConfig nacosConstant.ClientConfig
+	timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT))
+	if err != nil {
+		return nil, err
+	}
+	clientConfig.TimeoutMs = uint64(timeout.Seconds() * 1000)
+	clientConfig.ListenInterval = 2 * clientConfig.TimeoutMs
+	clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "")
+	clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "")
+	clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "")
+	clientConfig.NotLoadCacheAtStart = true
+	configMap["clientConfig"] = clientConfig
+
+	return configMap, nil
+}
+
+func newNacosRegistry(url *common.URL) (registry.Registry, error) {
+	nacosConfig, err := getNacosConfig(url)
+	if err != nil {
+		return nil, err
+	}
+	client, err := clients.CreateNamingClient(nacosConfig)
+	if err != nil {
+		return nil, err
+	}
+	registry := nacosRegistry{
+		URL:          url,
+		namingClient: client,
+	}
+	return &registry, nil
+}
+
+func getCategory(url common.URL) string {
+	role, _ := strconv.Atoi(url.GetParam(constant.ROLE_KEY, strconv.Itoa(constant.NACOS_DEFAULT_ROLETYPE)))
+	category := common.DubboNodes[role]
+	return category
+}
+
+func getServiceName(url common.URL) string {
+	var buffer bytes.Buffer
+
+	buffer.Write([]byte(getCategory(url)))
+	appendParam(&buffer, url, constant.INTERFACE_KEY)
+	appendParam(&buffer, url, constant.VERSION_KEY)
+	appendParam(&buffer, url, constant.GROUP_KEY)
+	return buffer.String()
+}
+
+func appendParam(target *bytes.Buffer, url common.URL, key string) {
+	value := url.GetParam(key, "")
+	if strings.TrimSpace(value) != "" {
+		target.Write([]byte(constant.NACOS_SERVICE_NAME_SEPARATOR))
+		target.Write([]byte(value))
+	}
+}
+
+func createRegisterParam(url common.URL, serviceName string) vo.RegisterInstanceParam {
+	category := getCategory(url)
+	params := make(map[string]string, len(url.Params)+3)
+	for k, _ := range url.Params {
+		params[k] = url.Params.Get(k)
+	}
+	params[constant.NACOS_CATEGORY_KEY] = category
+	params[constant.NACOS_PROTOCOL_KEY] = url.Protocol
+	params[constant.NACOS_PATH_KEY] = url.Path
+	if len(url.Ip) == 0 {
+		url.Ip = localIP
+	}
+	if len(url.Port) == 0 || url.Port == "0" {
+		url.Port = "80"
+	}
+	port, _ := strconv.Atoi(url.Port)
+	instance := vo.RegisterInstanceParam{
+		Ip:          url.Ip,
+		Port:        uint64(port),
+		Metadata:    params,
+		Weight:      1,
+		Enable:      true,
+		Healthy:     true,
+		Ephemeral:   true,
+		ServiceName: serviceName,
+	}
+	return instance
+}
+
+func (nr *nacosRegistry) Register(url common.URL) error {
+	serviceName := getServiceName(url)
+	param := createRegisterParam(url, serviceName)
+	isRegistry, err := nr.namingClient.RegisterInstance(param)
+	if err != nil {
+		return err
+	}
+	if !isRegistry {
+		return perrors.New("registry [" + serviceName + "] to  nacos failed")
+	}
+	return nil
+}
+
+func (nr *nacosRegistry) Subscribe(conf common.URL) (registry.Listener, error) {
+	return NewNacosListener(conf, nr.namingClient)
+}
+
+func (nr *nacosRegistry) GetUrl() common.URL {
+	return *nr.URL
+}
+
+func (nr *nacosRegistry) IsAvailable() bool {
+	return true
+}
+
+func (nr *nacosRegistry) Destroy() {
+	return
+}
diff --git a/registry/nacos/registry_test.go b/registry/nacos/registry_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..97dea0d2b016c8f84ee7cf6f4856ba545b720a48
--- /dev/null
+++ b/registry/nacos/registry_test.go
@@ -0,0 +1,174 @@
+package nacos
+
+import (
+	"context"
+	"encoding/json"
+	"net/url"
+	"strconv"
+	"testing"
+)
+
+import (
+	"github.com/nacos-group/nacos-sdk-go/vo"
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+)
+
+func Test_Register(t *testing.T) {
+	regurl, _ := common.NewURL(context.TODO(), "registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)))
+	urlMap := url.Values{}
+	urlMap.Set(constant.GROUP_KEY, "guangzhou-idc")
+	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
+	urlMap.Set(constant.INTERFACE_KEY, "com.ikurento.user.UserProvider")
+	urlMap.Set(constant.VERSION_KEY, "1.0.0")
+	urlMap.Set(constant.CLUSTER_KEY, "mock")
+	url, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"}))
+
+	reg, err := newNacosRegistry(&regurl)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("new nacos registry error:%s \n", err.Error())
+		return
+	}
+	err = reg.Register(url)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("register error:%s \n", err.Error())
+		return
+	}
+	nacosReg := reg.(*nacosRegistry)
+	service, _ := nacosReg.namingClient.GetService(vo.GetServiceParam{ServiceName: "providers:com.ikurento.user.UserProvider:1.0.0:guangzhou-idc"})
+	data, _ := json.Marshal(service)
+	t.Logf(string(data))
+	assert.Equal(t, 1, len(service.Hosts))
+}
+
+func TestNacosRegistry_Subscribe(t *testing.T) {
+	regurl, _ := common.NewURL(context.TODO(), "registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)))
+	urlMap := url.Values{}
+	urlMap.Set(constant.GROUP_KEY, "guangzhou-idc")
+	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
+	urlMap.Set(constant.INTERFACE_KEY, "com.ikurento.user.UserProvider")
+	urlMap.Set(constant.VERSION_KEY, "1.0.0")
+	urlMap.Set(constant.CLUSTER_KEY, "mock")
+	urlMap.Set(constant.NACOS_PATH_KEY, "")
+	url, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"}))
+
+	reg, _ := newNacosRegistry(&regurl)
+	err := reg.Register(url)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("new nacos registry error:%s \n", err.Error())
+		return
+	}
+
+	regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+	reg2, _ := newNacosRegistry(&regurl)
+	listener, err := reg2.Subscribe(url)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("subscribe error:%s \n", err.Error())
+		return
+	}
+	serviceEvent, _ := listener.Next()
+	assert.NoError(t, err)
+	if err != nil {
+		t.Errorf("listener error:%s \n", err.Error())
+		return
+	}
+	t.Logf("serviceEvent:%+v \n", serviceEvent)
+	assert.Regexp(t, ".*ServiceEvent{Action{add}.*", serviceEvent.String())
+
+}
+
+func TestNacosRegistry_Subscribe_del(t *testing.T) {
+	regurl, _ := common.NewURL(context.TODO(), "registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)))
+	urlMap := url.Values{}
+	urlMap.Set(constant.GROUP_KEY, "guangzhou-idc")
+	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
+	urlMap.Set(constant.INTERFACE_KEY, "com.ikurento.user.UserProvider")
+	urlMap.Set(constant.VERSION_KEY, "1.0.0")
+	urlMap.Set(constant.CLUSTER_KEY, "mock")
+	urlMap.Set(constant.NACOS_PATH_KEY, "")
+	url1, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"}))
+	url2, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.2:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"}))
+
+	reg, _ := newNacosRegistry(&regurl)
+	err := reg.Register(url1)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("register1 error:%s \n", err.Error())
+		return
+	}
+	err = reg.Register(url2)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("register2 error:%s \n", err.Error())
+		return
+	}
+
+	regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+	reg2, _ := newNacosRegistry(&regurl)
+	listener, err := reg2.Subscribe(url1)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("subscribe error:%s \n", err.Error())
+		return
+	}
+
+	serviceEvent1, _ := listener.Next()
+	assert.NoError(t, err)
+	if err != nil {
+		t.Errorf("listener1 error:%s \n", err.Error())
+		return
+	}
+	t.Logf("serviceEvent1:%+v \n", serviceEvent1)
+	assert.Regexp(t, ".*ServiceEvent{Action{add}.*", serviceEvent1.String())
+
+	serviceEvent2, _ := listener.Next()
+	assert.NoError(t, err)
+	if err != nil {
+		t.Errorf("listener2 error:%s \n", err.Error())
+		return
+	}
+	t.Logf("serviceEvent2:%+v \n", serviceEvent2)
+	assert.Regexp(t, ".*ServiceEvent{Action{add}.*", serviceEvent2.String())
+
+	nacosReg := reg.(*nacosRegistry)
+	//deregister  instance to mock instance offline
+	nacosReg.namingClient.DeregisterInstance(vo.DeregisterInstanceParam{Ip: "127.0.0.2", Port: 20000, ServiceName: "providers:com.ikurento.user.UserProvider:1.0.0:guangzhou-idc"})
+
+	serviceEvent3, _ := listener.Next()
+	assert.NoError(t, err)
+	if err != nil {
+		return
+	}
+	t.Logf("serviceEvent3:%+v \n", serviceEvent3)
+	assert.Regexp(t, ".*ServiceEvent{Action{delete}.*", serviceEvent3.String())
+}
+
+func TestNacosListener_Close(t *testing.T) {
+	regurl, _ := common.NewURL(context.TODO(), "registry://console.nacos.io:80", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)))
+	urlMap := url.Values{}
+	urlMap.Set(constant.GROUP_KEY, "guangzhou-idc")
+	urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
+	urlMap.Set(constant.INTERFACE_KEY, "com.ikurento.user.UserProvider2")
+	urlMap.Set(constant.VERSION_KEY, "1.0.0")
+	urlMap.Set(constant.CLUSTER_KEY, "mock")
+	urlMap.Set(constant.NACOS_PATH_KEY, "")
+	url1, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider2", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"}))
+	reg, _ := newNacosRegistry(&regurl)
+	listener, err := reg.Subscribe(url1)
+	assert.Nil(t, err)
+	if err != nil {
+		t.Errorf("subscribe error:%s \n", err.Error())
+		return
+	}
+	listener.Close()
+	_, err = listener.Next()
+	assert.NotNil(t, err)
+}
diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go
index 67f20370602a0a9c5c3d87ef93b1bafed3449d36..7d58cee1220b9aedba353d929ca1e936cf9366f2 100644
--- a/registry/zookeeper/listener.go
+++ b/registry/zookeeper/listener.go
@@ -45,11 +45,16 @@ func (l *RegistryDataListener) AddInterestedURL(url *common.URL) {
 }
 
 func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool {
-	//截取最后一位
-	url := eventType.Path[strings.Index(eventType.Path, "/providers/")+len("/providers/"):]
+	// Intercept the last bit
+	index := strings.Index(eventType.Path, "/providers/")
+	if index == -1 {
+		logger.Warn("Listen with no url, event.path={%v}", eventType.Path)
+		return false
+	}
+	url := eventType.Path[index+len("/providers/"):]
 	serviceURL, err := common.NewURL(context.TODO(), url)
 	if err != nil {
-		logger.Errorf("Listen NewURL(r{%s}) = error{%v}", url, err)
+		logger.Errorf("Listen NewURL(r{%s}) = error{%v} eventType.Path={%v}", url, err, eventType.Path)
 		return false
 	}
 	for _, v := range l.interestedURL {
diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go
index 0f4f57917bb53c61aa6ad8c700d11e2d9582b151..e86b7cfccad5fc03dfce56d2501af021a3cfe624 100644
--- a/registry/zookeeper/registry.go
+++ b/registry/zookeeper/registry.go
@@ -41,7 +41,6 @@ import (
 	"github.com/apache/dubbo-go/common/utils"
 	"github.com/apache/dubbo-go/registry"
 	"github.com/apache/dubbo-go/remoting/zookeeper"
-	"github.com/apache/dubbo-go/version"
 )
 
 const (
@@ -231,10 +230,11 @@ func (r *zkRegistry) Register(conf common.URL) error {
 
 	case common.PROVIDER:
 
-		// 检验服务是否已经注册过
+		// Check if the service has been registered
 		r.cltLock.Lock()
-		// 注意此处与consumerZookeeperRegistry的差异,consumer用的是conf.Path,
-		// 因为consumer要提供watch功能给selector使用, provider允许注册同一个service的多个group or version
+		// Note the difference between consumer and consumerZookeeperRegistry (consumer use conf.Path).
+		// Because the consumer wants to provide monitoring functions for the selector,
+		// the provider allows multiple groups or versions of the same service to be registered.
 		_, ok = r.services[conf.Key()]
 		r.cltLock.Unlock()
 		if ok {
@@ -299,11 +299,12 @@ func (r *zkRegistry) register(c common.URL) error {
 		}
 		params.Add("anyhost", "true")
 
-		// dubbo java consumer来启动找provider url时,因为category不匹配,会找不到provider,导致consumer启动不了,所以使用consumers&providers
+		// Dubbo java consumer to start looking for the provider url,because the category does not match,
+		// the provider will not find, causing the consumer can not start, so we use consumers.
 		// DubboRole               = [...]string{"consumer", "", "", "provider"}
 		// params.Add("category", (RoleType(PROVIDER)).Role())
 		params.Add("category", (common.RoleType(common.PROVIDER)).String())
-		params.Add("dubbo", "dubbo-provider-golang-"+version.Version)
+		params.Add("dubbo", "dubbo-provider-golang-"+constant.Version)
 
 		params.Add("side", (common.RoleType(common.PROVIDER)).Role())
 
@@ -321,7 +322,7 @@ func (r *zkRegistry) register(c common.URL) error {
 		rawURL = fmt.Sprintf("%s://%s%s?%s", c.Protocol, host, c.Path, params.Encode())
 		encodedURL = url.QueryEscape(rawURL)
 
-		// 把自己注册service providers
+		// Print your own registration service providers.
 		dubboPath = fmt.Sprintf("/dubbo/%s/%s", c.Service(), (common.RoleType(common.PROVIDER)).String())
 		logger.Debugf("provider path:%s, url:%s", dubboPath, rawURL)
 
@@ -346,7 +347,7 @@ func (r *zkRegistry) register(c common.URL) error {
 		params.Add("protocol", c.Protocol)
 
 		params.Add("category", (common.RoleType(common.CONSUMER)).String())
-		params.Add("dubbo", "dubbogo-consumer-"+version.Version)
+		params.Add("dubbo", "dubbogo-consumer-"+constant.Version)
 
 		rawURL = fmt.Sprintf("consumer://%s%s?%s", localIP, c.Path, params.Encode())
 		encodedURL = url.QueryEscape(rawURL)
@@ -381,7 +382,11 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error {
 	}
 	zkPath, err = r.client.RegisterTemp(root, node)
 	if err != nil {
-		logger.Errorf("RegisterTempNode(root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err))
+		if err == zk.ErrNodeExists {
+			logger.Warnf("RegisterTempNode(root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err))
+		} else {
+			logger.Errorf("RegisterTempNode(root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err))
+		}
 		return perrors.WithMessagef(err, "RegisterTempNode(root{%s}, node{%s})", root, node)
 	}
 	logger.Debugf("create a zookeeper node:%s", zkPath)
@@ -452,7 +457,7 @@ func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListen
 		r.listenerLock.Unlock()
 	}
 
-	//注册到dataconfig的interested
+	//Interested register to dataconfig.
 	r.dataListener.AddInterestedURL(conf)
 
 	go r.listener.ListenServiceEvent(fmt.Sprintf("/dubbo/%s/"+conf.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY), conf.Service()), r.dataListener)
@@ -464,7 +469,7 @@ func (r *zkRegistry) closeRegisters() {
 	r.cltLock.Lock()
 	defer r.cltLock.Unlock()
 	logger.Infof("begin to close provider zk client")
-	// 先关闭旧client,以关闭tmp node
+	// Close the old client first to close the tmp node.
 	r.client.Close()
 	r.client = nil
 	r.services = nil
diff --git a/registry/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar b/registry/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar
deleted file mode 100644
index 839531b8b8762a9c19e334a5cbf79314cb16f945..0000000000000000000000000000000000000000
Binary files a/registry/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar and /dev/null differ
diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..57d1211fe30e00dcb1ad16733f36b7969ebaf505
--- /dev/null
+++ b/remoting/etcdv3/client.go
@@ -0,0 +1,480 @@
+package etcdv3
+
+import (
+	"context"
+	"path"
+	"sync"
+	"time"
+)
+
+import (
+	"github.com/coreos/etcd/clientv3"
+	"github.com/coreos/etcd/clientv3/concurrency"
+	perrors "github.com/pkg/errors"
+	"google.golang.org/grpc"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/logger"
+)
+
+const (
+	ConnDelay            = 3
+	MaxFailTimes         = 15
+	RegistryETCDV3Client = "etcd registry"
+)
+
+var (
+	ErrNilETCDV3Client = perrors.New("etcd raw client is nil") // full describe the ERR
+	ErrKVPairNotFound  = perrors.New("k/v pair not found")
+)
+
+type Options struct {
+	name      string
+	endpoints []string
+	client    *Client
+	timeout   time.Duration
+	heartbeat int // heartbeat second
+}
+
+type Option func(*Options)
+
+func WithEndpoints(endpoints ...string) Option {
+	return func(opt *Options) {
+		opt.endpoints = endpoints
+	}
+}
+func WithName(name string) Option {
+	return func(opt *Options) {
+		opt.name = name
+	}
+}
+func WithTimeout(timeout time.Duration) Option {
+	return func(opt *Options) {
+		opt.timeout = timeout
+	}
+}
+
+func WithHeartbeat(heartbeat int) Option {
+	return func(opt *Options) {
+		opt.heartbeat = heartbeat
+	}
+}
+
+func ValidateClient(container clientFacade, opts ...Option) error {
+
+	options := &Options{
+		heartbeat: 1, // default heartbeat
+	}
+	for _, opt := range opts {
+		opt(options)
+	}
+
+	lock := container.ClientLock()
+	lock.Lock()
+	defer lock.Unlock()
+
+	// new Client
+	if container.Client() == nil {
+		newClient, err := newClient(options.name, options.endpoints, options.timeout, options.heartbeat)
+		if err != nil {
+			logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}",
+				options.name, options.endpoints, options.timeout, err)
+			return perrors.WithMessagef(err, "new client (address:%+v)", options.endpoints)
+		}
+		container.SetClient(newClient)
+	}
+
+	// Client lose connection with etcd server
+	if container.Client().rawClient == nil {
+
+		newClient, err := newClient(options.name, options.endpoints, options.timeout, options.heartbeat)
+		if err != nil {
+			logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}",
+				options.name, options.endpoints, options.timeout, err)
+			return perrors.WithMessagef(err, "new client (address:%+v)", options.endpoints)
+		}
+		container.SetClient(newClient)
+	}
+
+	return nil
+}
+
+type Client struct {
+	lock sync.RWMutex
+
+	// these properties are only set once when they are started.
+	name      string
+	endpoints []string
+	timeout   time.Duration
+	heartbeat int
+
+	ctx       context.Context    // if etcd server connection lose, the ctx.Done will be sent msg
+	cancel    context.CancelFunc // cancel the ctx,  all watcher will stopped
+	rawClient *clientv3.Client
+
+	exit chan struct{}
+	Wait sync.WaitGroup
+}
+
+func newClient(name string, endpoints []string, timeout time.Duration, heartbeat int) (*Client, error) {
+
+	ctx, cancel := context.WithCancel(context.Background())
+	rawClient, err := clientv3.New(clientv3.Config{
+		Context:     ctx,
+		Endpoints:   endpoints,
+		DialTimeout: timeout,
+		DialOptions: []grpc.DialOption{grpc.WithBlock()},
+	})
+	if err != nil {
+		return nil, perrors.WithMessage(err, "new raw client block connect to server")
+	}
+
+	c := &Client{
+
+		name:      name,
+		timeout:   timeout,
+		endpoints: endpoints,
+		heartbeat: heartbeat,
+
+		ctx:       ctx,
+		cancel:    cancel,
+		rawClient: rawClient,
+
+		exit: make(chan struct{}),
+	}
+
+	if err := c.maintenanceStatus(); err != nil {
+		return nil, perrors.WithMessage(err, "client maintenance status")
+	}
+	return c, nil
+}
+
+// NOTICE: need to get the lock before calling this method
+func (c *Client) clean() {
+
+	// close raw client
+	c.rawClient.Close()
+
+	// cancel ctx for raw client
+	c.cancel()
+
+	// clean raw client
+	c.rawClient = nil
+}
+
+func (c *Client) stop() bool {
+
+	select {
+	case <-c.exit:
+		return true
+	default:
+		close(c.exit)
+	}
+	return false
+}
+
+func (c *Client) Close() {
+
+	if c == nil {
+		return
+	}
+
+	// stop the client
+	c.stop()
+
+	// wait client maintenance status stop
+	c.Wait.Wait()
+
+	c.lock.Lock()
+	if c.rawClient != nil {
+		c.clean()
+	}
+	c.lock.Unlock()
+	logger.Warnf("etcd client{name:%s, endpoints:%s} exit now.", c.name, c.endpoints)
+}
+
+func (c *Client) maintenanceStatus() error {
+
+	s, err := concurrency.NewSession(c.rawClient, concurrency.WithTTL(c.heartbeat))
+	if err != nil {
+		return perrors.WithMessage(err, "new session with server")
+	}
+
+	// must add wg before go maintenance status goroutine
+	c.Wait.Add(1)
+	go c.maintenanceStatusLoop(s)
+	return nil
+}
+
+func (c *Client) maintenanceStatusLoop(s *concurrency.Session) {
+
+	defer func() {
+		c.Wait.Done()
+		logger.Infof("etcd client {endpoints:%v, name:%s} maintenance goroutine game over.", c.endpoints, c.name)
+	}()
+
+	for {
+		select {
+		case <-c.Done():
+			// Client be stopped, will clean the client hold resources
+			return
+		case <-s.Done():
+			logger.Warn("etcd server stopped")
+			c.lock.Lock()
+			// when etcd server stopped, cancel ctx, stop all watchers
+			c.clean()
+			// when connection lose, stop client, trigger reconnect to etcd
+			c.stop()
+			c.lock.Unlock()
+			return
+		}
+	}
+}
+
+// if k not exist will put k/v in etcd
+// if k is already exist in etcd, return nil
+func (c *Client) put(k string, v string, opts ...clientv3.OpOption) error {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return ErrNilETCDV3Client
+	}
+
+	_, err := c.rawClient.Txn(c.ctx).
+		If(clientv3.Compare(clientv3.Version(k), "<", 1)).
+		Then(clientv3.OpPut(k, v, opts...)).
+		Commit()
+	if err != nil {
+		return err
+
+	}
+	return nil
+}
+
+func (c *Client) delete(k string) error {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return ErrNilETCDV3Client
+	}
+
+	_, err := c.rawClient.Delete(c.ctx, k)
+	if err != nil {
+		return err
+
+	}
+	return nil
+}
+
+func (c *Client) get(k string) (string, error) {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return "", ErrNilETCDV3Client
+	}
+
+	resp, err := c.rawClient.Get(c.ctx, k)
+	if err != nil {
+		return "", err
+	}
+
+	if len(resp.Kvs) == 0 {
+		return "", ErrKVPairNotFound
+	}
+
+	return string(resp.Kvs[0].Value), nil
+}
+
+func (c *Client) CleanKV() error {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return ErrNilETCDV3Client
+	}
+
+	_, err := c.rawClient.Delete(c.ctx, "", clientv3.WithPrefix())
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *Client) getChildren(k string) ([]string, []string, error) {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return nil, nil, ErrNilETCDV3Client
+	}
+
+	resp, err := c.rawClient.Get(c.ctx, k, clientv3.WithPrefix())
+	if err != nil {
+		return nil, nil, err
+	}
+
+	if len(resp.Kvs) == 0 {
+		return nil, nil, ErrKVPairNotFound
+	}
+
+	var (
+		kList []string
+		vList []string
+	)
+
+	for _, kv := range resp.Kvs {
+		kList = append(kList, string(kv.Key))
+		vList = append(vList, string(kv.Value))
+	}
+
+	return kList, vList, nil
+}
+
+func (c *Client) watchWithPrefix(prefix string) (clientv3.WatchChan, error) {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return nil, ErrNilETCDV3Client
+	}
+
+	return c.rawClient.Watch(c.ctx, prefix, clientv3.WithPrefix()), nil
+}
+
+func (c *Client) watch(k string) (clientv3.WatchChan, error) {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return nil, ErrNilETCDV3Client
+	}
+
+	return c.rawClient.Watch(c.ctx, k), nil
+}
+
+func (c *Client) keepAliveKV(k string, v string) error {
+
+	c.lock.RLock()
+	defer c.lock.RUnlock()
+
+	if c.rawClient == nil {
+		return ErrNilETCDV3Client
+	}
+
+	lease, err := c.rawClient.Grant(c.ctx, int64(time.Second.Seconds()))
+	if err != nil {
+		return perrors.WithMessage(err, "grant lease")
+	}
+
+	keepAlive, err := c.rawClient.KeepAlive(c.ctx, lease.ID)
+	if err != nil || keepAlive == nil {
+		c.rawClient.Revoke(c.ctx, lease.ID)
+		return perrors.WithMessage(err, "keep alive lease")
+	}
+
+	_, err = c.rawClient.Put(c.ctx, k, v, clientv3.WithLease(lease.ID))
+	if err != nil {
+		return perrors.WithMessage(err, "put k/v with lease")
+	}
+	return nil
+}
+
+func (c *Client) Done() <-chan struct{} {
+	return c.exit
+}
+
+func (c *Client) Valid() bool {
+	select {
+	case <-c.exit:
+		return false
+	default:
+	}
+
+	c.lock.RLock()
+	if c.rawClient == nil {
+		c.lock.RUnlock()
+		return false
+	}
+	c.lock.RUnlock()
+	return true
+}
+
+func (c *Client) Create(k string, v string) error {
+
+	err := c.put(k, v)
+	if err != nil {
+		return perrors.WithMessagef(err, "put k/v (key: %s value %s)", k, v)
+	}
+	return nil
+}
+
+func (c *Client) Delete(k string) error {
+
+	err := c.delete(k)
+	if err != nil {
+		return perrors.WithMessagef(err, "delete k/v (key %s)", k)
+	}
+
+	return nil
+}
+
+func (c *Client) RegisterTemp(basePath string, node string) (string, error) {
+
+	completeKey := path.Join(basePath, node)
+
+	err := c.keepAliveKV(completeKey, "")
+	if err != nil {
+		return "", perrors.WithMessagef(err, "keepalive kv (key %s)", completeKey)
+	}
+
+	return completeKey, nil
+}
+
+func (c *Client) GetChildrenKVList(k string) ([]string, []string, error) {
+
+	kList, vList, err := c.getChildren(k)
+	if err != nil {
+		return nil, nil, perrors.WithMessagef(err, "get key children (key %s)", k)
+	}
+	return kList, vList, nil
+}
+
+func (c *Client) Get(k string) (string, error) {
+
+	v, err := c.get(k)
+	if err != nil {
+		return "", perrors.WithMessagef(err, "get key value (key %s)", k)
+	}
+
+	return v, nil
+}
+
+func (c *Client) Watch(k string) (clientv3.WatchChan, error) {
+
+	wc, err := c.watch(k)
+	if err != nil {
+		return nil, perrors.WithMessagef(err, "watch prefix (key %s)", k)
+	}
+	return wc, nil
+}
+
+func (c *Client) WatchWithPrefix(prefix string) (clientv3.WatchChan, error) {
+
+	wc, err := c.watchWithPrefix(prefix)
+	if err != nil {
+		return nil, perrors.WithMessagef(err, "watch prefix (key %s)", prefix)
+	}
+	return wc, nil
+}
diff --git a/remoting/etcdv3/client_test.go b/remoting/etcdv3/client_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..187789e0abfac6a0e195bebd68ce4b91e0f9bdec
--- /dev/null
+++ b/remoting/etcdv3/client_test.go
@@ -0,0 +1,366 @@
+package etcdv3
+
+import (
+	"fmt"
+	"net/url"
+	"path"
+	"reflect"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/coreos/etcd/mvcc/mvccpb"
+	perrors "github.com/pkg/errors"
+	"github.com/stretchr/testify/suite"
+	"go.etcd.io/etcd/embed"
+	"google.golang.org/grpc/connectivity"
+)
+
+// tests dataset
+var tests = []struct {
+	input struct {
+		k string
+		v string
+	}
+}{
+	{input: struct {
+		k string
+		v string
+	}{k: "name", v: "scott.wang"}},
+	{input: struct {
+		k string
+		v string
+	}{k: "namePrefix", v: "prefix.scott.wang"}},
+	{input: struct {
+		k string
+		v string
+	}{k: "namePrefix1", v: "prefix1.scott.wang"}},
+	{input: struct {
+		k string
+		v string
+	}{k: "age", v: "27"}},
+}
+
+// test dataset prefix
+const prefix = "name"
+
+type ClientTestSuite struct {
+	suite.Suite
+
+	etcdConfig struct {
+		name      string
+		endpoints []string
+		timeout   time.Duration
+		heartbeat int
+	}
+
+	etcd *embed.Etcd
+
+	client *Client
+}
+
+// start etcd server
+func (suite *ClientTestSuite) SetupSuite() {
+
+	t := suite.T()
+
+	DefaultListenPeerURLs := "http://localhost:2382"
+	DefaultListenClientURLs := "http://localhost:2381"
+	lpurl, _ := url.Parse(DefaultListenPeerURLs)
+	lcurl, _ := url.Parse(DefaultListenClientURLs)
+	cfg := embed.NewConfig()
+	cfg.LPUrls = []url.URL{*lpurl}
+	cfg.LCUrls = []url.URL{*lcurl}
+	cfg.Dir = "/tmp/default.etcd"
+	e, err := embed.StartEtcd(cfg)
+	if err != nil {
+		t.Fatal(err)
+	}
+	select {
+	case <-e.Server.ReadyNotify():
+		t.Log("Server is ready!")
+	case <-time.After(60 * time.Second):
+		e.Server.Stop() // trigger a shutdown
+		t.Logf("Server took too long to start!")
+	}
+
+	suite.etcd = e
+	return
+}
+
+// stop etcd server
+func (suite *ClientTestSuite) TearDownSuite() {
+	suite.etcd.Close()
+}
+
+func (suite *ClientTestSuite) setUpClient() *Client {
+	c, err := newClient(suite.etcdConfig.name,
+		suite.etcdConfig.endpoints,
+		suite.etcdConfig.timeout,
+		suite.etcdConfig.heartbeat)
+	if err != nil {
+		suite.T().Fatal(err)
+	}
+	return c
+}
+
+// set up a client for suite
+func (suite *ClientTestSuite) SetupTest() {
+	c := suite.setUpClient()
+	c.CleanKV()
+	suite.client = c
+	return
+}
+
+func (suite *ClientTestSuite) TestClientClose() {
+
+	fmt.Println("called client close")
+
+	c := suite.client
+	t := suite.T()
+
+	defer c.Close()
+	if c.rawClient.ActiveConnection().GetState() != connectivity.Ready {
+		t.Fatal(suite.client.rawClient.ActiveConnection().GetState())
+	}
+}
+
+func (suite *ClientTestSuite) TestClientValid() {
+
+	fmt.Println("called client valid")
+
+	c := suite.client
+	t := suite.T()
+
+	if c.Valid() != true {
+		t.Fatal("client is not valid")
+	}
+	c.Close()
+	if suite.client.Valid() != false {
+		t.Fatal("client is valid")
+	}
+}
+
+func (suite *ClientTestSuite) TestClientDone() {
+
+	c := suite.client
+
+	go func() {
+		time.Sleep(2 * time.Second)
+		c.Close()
+	}()
+
+	c.Wait.Wait()
+}
+
+func (suite *ClientTestSuite) TestClientCreateKV() {
+
+	tests := tests
+
+	c := suite.client
+	t := suite.T()
+
+	defer suite.client.Close()
+
+	for _, tc := range tests {
+
+		k := tc.input.k
+		v := tc.input.v
+		expect := tc.input.v
+
+		if err := c.Create(k, v); err != nil {
+			t.Fatal(err)
+		}
+
+		value, err := c.Get(k)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if value != expect {
+			t.Fatalf("expect %v but get %v", expect, value)
+		}
+
+	}
+}
+
+func (suite *ClientTestSuite) TestClientDeleteKV() {
+
+	tests := tests
+	c := suite.client
+	t := suite.T()
+
+	defer c.Close()
+
+	for _, tc := range tests {
+
+		k := tc.input.k
+		v := tc.input.v
+		expect := ErrKVPairNotFound
+
+		if err := c.Create(k, v); err != nil {
+			t.Fatal(err)
+		}
+
+		if err := c.Delete(k); err != nil {
+			t.Fatal(err)
+		}
+
+		_, err := c.Get(k)
+		if perrors.Cause(err) == expect {
+			continue
+		}
+
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+}
+
+func (suite *ClientTestSuite) TestClientGetChildrenKVList() {
+
+	tests := tests
+
+	c := suite.client
+	t := suite.T()
+
+	var expectKList []string
+	var expectVList []string
+
+	for _, tc := range tests {
+
+		k := tc.input.k
+		v := tc.input.v
+
+		if strings.Contains(k, prefix) {
+			expectKList = append(expectKList, k)
+			expectVList = append(expectVList, v)
+		}
+
+		if err := c.Create(k, v); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	kList, vList, err := c.GetChildrenKVList(prefix)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if reflect.DeepEqual(expectKList, kList) && reflect.DeepEqual(expectVList, vList) {
+		return
+	}
+
+	t.Fatalf("expect keylist %v but got %v expect valueList %v but got %v ", expectKList, kList, expectVList, vList)
+
+}
+
+func (suite *ClientTestSuite) TestClientWatch() {
+
+	tests := tests
+
+	c := suite.client
+	t := suite.T()
+
+	wg := sync.WaitGroup{}
+	wg.Add(1)
+
+	go func() {
+
+		defer wg.Done()
+
+		wc, err := c.watch(prefix)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		for e := range wc {
+
+			for _, event := range e.Events {
+				t.Logf("type IsCreate %v k %s v %s", event.IsCreate(), event.Kv.Key, event.Kv.Value)
+			}
+		}
+
+	}()
+
+	for _, tc := range tests {
+
+		k := tc.input.k
+		v := tc.input.v
+
+		if err := c.Create(k, v); err != nil {
+			t.Fatal(err)
+		}
+
+		if err := c.delete(k); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	c.Close()
+
+	wg.Wait()
+
+}
+
+func (suite *ClientTestSuite) TestClientRegisterTemp() {
+
+	c := suite.client
+	observeC := suite.setUpClient()
+	t := suite.T()
+
+	wg := sync.WaitGroup{}
+	wg.Add(1)
+
+	go func() {
+		completePath := path.Join("scott", "wang")
+		wc, err := observeC.watch(completePath)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		for e := range wc {
+
+			for _, event := range e.Events {
+
+				if event.Type == mvccpb.DELETE {
+					t.Logf("complete key (%s) is delete", completePath)
+					wg.Done()
+					observeC.Close()
+					return
+				}
+				t.Logf("type IsCreate %v k %s v %s", event.IsCreate(), event.Kv.Key, event.Kv.Value)
+			}
+		}
+	}()
+
+	_, err := c.RegisterTemp("scott", "wang")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	time.Sleep(2 * time.Second)
+	c.Close()
+
+	wg.Wait()
+}
+
+func TestClientSuite(t *testing.T) {
+	suite.Run(t, &ClientTestSuite{
+		etcdConfig: struct {
+			name      string
+			endpoints []string
+			timeout   time.Duration
+			heartbeat int
+		}{
+			name:      "test",
+			endpoints: []string{"localhost:2381"},
+			timeout:   time.Second,
+			heartbeat: 1,
+		},
+	})
+}
diff --git a/remoting/etcdv3/facade.go b/remoting/etcdv3/facade.go
new file mode 100644
index 0000000000000000000000000000000000000000..e75b39d6bcd7f67f7606c6b212f59e7a42178fd8
--- /dev/null
+++ b/remoting/etcdv3/facade.go
@@ -0,0 +1,82 @@
+package etcdv3
+
+import (
+	"sync"
+	"time"
+)
+
+import (
+	"github.com/dubbogo/getty"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+)
+
+type clientFacade interface {
+	Client() *Client
+	SetClient(*Client)
+	ClientLock() *sync.Mutex
+	WaitGroup() *sync.WaitGroup //for wait group control, etcd client listener & etcd client container
+	GetDone() chan struct{}     //for etcd client control
+	RestartCallBack() bool
+	common.Node
+}
+
+func HandleClientRestart(r clientFacade) {
+
+	var (
+		err       error
+		failTimes int
+	)
+
+	defer r.WaitGroup().Done()
+LOOP:
+	for {
+		select {
+		case <-r.GetDone():
+			logger.Warnf("(ETCDV3ProviderRegistry)reconnectETCDV3 goroutine exit now...")
+			break LOOP
+			// re-register all services
+		case <-r.Client().Done():
+			r.ClientLock().Lock()
+			clientName := RegistryETCDV3Client
+			timeout, _ := time.ParseDuration(r.GetUrl().GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT))
+			endpoint := r.GetUrl().Location
+			r.Client().Close()
+			r.SetClient(nil)
+			r.ClientLock().Unlock()
+
+			// try to connect to etcd,
+			failTimes = 0
+			for {
+				select {
+				case <-r.GetDone():
+					logger.Warnf("(ETCDV3ProviderRegistry)reconnectETCDRegistry goroutine exit now...")
+					break LOOP
+				case <-getty.GetTimeWheel().After(timeSecondDuration(failTimes * ConnDelay)): // avoid connect frequent
+				}
+				err = ValidateClient(
+					r,
+					WithName(clientName),
+					WithEndpoints(endpoint),
+					WithTimeout(timeout),
+				)
+				logger.Infof("ETCDV3ProviderRegistry.validateETCDV3Client(etcd Addr{%s}) = error{%#v}",
+					endpoint, perrors.WithStack(err))
+				if err == nil {
+					if r.RestartCallBack() {
+						break
+					}
+				}
+				failTimes++
+				if MaxFailTimes <= failTimes {
+					failTimes = MaxFailTimes
+				}
+			}
+		}
+	}
+}
diff --git a/remoting/etcdv3/listener.go b/remoting/etcdv3/listener.go
new file mode 100644
index 0000000000000000000000000000000000000000..59273af554a63e5fc907ba5a30bb1e18bb22c0f5
--- /dev/null
+++ b/remoting/etcdv3/listener.go
@@ -0,0 +1,217 @@
+package etcdv3
+
+import (
+	"sync"
+	"time"
+)
+
+import (
+	"github.com/coreos/etcd/clientv3"
+	"github.com/coreos/etcd/mvcc/mvccpb"
+	perrors "github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+type EventListener struct {
+	client     *Client
+	keyMapLock sync.Mutex
+	keyMap     map[string]struct{}
+	wg         sync.WaitGroup
+}
+
+func NewEventListener(client *Client) *EventListener {
+	return &EventListener{
+		client: client,
+		keyMap: make(map[string]struct{}),
+	}
+}
+
+// Listen on a spec key
+// this method will return true when spec key deleted,
+// this method will return false when deep layer connection lose
+func (l *EventListener) ListenServiceNodeEvent(key string, listener ...remoting.DataListener) bool {
+	l.wg.Add(1)
+	defer l.wg.Done()
+	for {
+		wc, err := l.client.Watch(key)
+		if err != nil {
+			logger.Warnf("WatchExist{key:%s} = error{%v}", key, err)
+			return false
+		}
+
+		select {
+
+		// client stopped
+		case <-l.client.Done():
+			logger.Warnf("etcd client stopped")
+			return false
+
+		// client ctx stop
+		case <-l.client.ctx.Done():
+			logger.Warnf("etcd client ctx cancel")
+			return false
+
+		// handle etcd events
+		case e, ok := <-wc:
+			if !ok {
+				logger.Warnf("etcd watch-chan closed")
+				return false
+			}
+
+			if e.Err() != nil {
+				logger.Errorf("etcd watch ERR {err: %s}", e.Err())
+				continue
+			}
+			for _, event := range e.Events {
+				if l.handleEvents(event, listener...) {
+					// if event is delete
+					return true
+				}
+			}
+		}
+	}
+
+	return false
+}
+
+// return true mean the event type is DELETE
+// return false mean the event type is CREATE || UPDATE
+func (l *EventListener) handleEvents(event *clientv3.Event, listeners ...remoting.DataListener) bool {
+
+	logger.Infof("got a etcd event {type: %s, key: %s}", event.Type, event.Kv.Key)
+
+	switch event.Type {
+	// the etcdv3 event just include PUT && DELETE
+	case mvccpb.PUT:
+		for _, listener := range listeners {
+			switch event.IsCreate() {
+			case true:
+				logger.Infof("etcd get event (key{%s}) = event{EventNodeDataCreated}", event.Kv.Key)
+				listener.DataChange(remoting.Event{
+					Path:    string(event.Kv.Key),
+					Action:  remoting.EventTypeAdd,
+					Content: string(event.Kv.Value),
+				})
+			case false:
+				logger.Infof("etcd get event (key{%s}) = event{EventNodeDataChanged}", event.Kv.Key)
+				listener.DataChange(remoting.Event{
+					Path:    string(event.Kv.Key),
+					Action:  remoting.EvnetTypeUpdate,
+					Content: string(event.Kv.Value),
+				})
+			}
+		}
+		return false
+	case mvccpb.DELETE:
+		logger.Warnf("etcd get event (key{%s}) = event{EventNodeDeleted}", event.Kv.Key)
+		return true
+
+	default:
+		return false
+	}
+
+	panic("unreachable")
+}
+
+// Listen on a set of key with spec prefix
+func (l *EventListener) ListenServiceNodeEventWithPrefix(prefix string, listener ...remoting.DataListener) {
+
+	l.wg.Add(1)
+	defer l.wg.Done()
+	for {
+		wc, err := l.client.WatchWithPrefix(prefix)
+		if err != nil {
+			logger.Warnf("listenDirEvent(key{%s}) = error{%v}", prefix, err)
+		}
+
+		select {
+
+		// client stopped
+		case <-l.client.Done():
+			logger.Warnf("etcd client stopped")
+			return
+
+			// client ctx stop
+		case <-l.client.ctx.Done():
+			logger.Warnf("etcd client ctx cancel")
+			return
+
+			// etcd event stream
+		case e, ok := <-wc:
+
+			if !ok {
+				logger.Warnf("etcd watch-chan closed")
+				return
+			}
+
+			if e.Err() != nil {
+				logger.Errorf("etcd watch ERR {err: %s}", e.Err())
+				continue
+			}
+			for _, event := range e.Events {
+				l.handleEvents(event, listener...)
+			}
+		}
+	}
+}
+
+func timeSecondDuration(sec int) time.Duration {
+	return time.Duration(sec) * time.Second
+}
+
+// this func is invoked by etcdv3 ConsumerRegistry::Registe/ etcdv3 ConsumerRegistry::get/etcdv3 ConsumerRegistry::getListener
+// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> ListenServiceNodeEvent
+//                            |
+//                            --------> ListenServiceNodeEvent
+func (l *EventListener) ListenServiceEvent(key string, listener remoting.DataListener) {
+
+	l.keyMapLock.Lock()
+	_, ok := l.keyMap[key]
+	l.keyMapLock.Unlock()
+	if ok {
+		logger.Warnf("etcdv3 key %s has already been listened.", key)
+		return
+	}
+
+	l.keyMapLock.Lock()
+	l.keyMap[key] = struct{}{}
+	l.keyMapLock.Unlock()
+
+	keyList, valueList, err := l.client.getChildren(key)
+	if err != nil {
+		logger.Errorf("Get new node path {%v} 's content error,message is  {%v}", key, perrors.WithMessage(err, "get children"))
+	}
+
+	logger.Infof("get key children list %s, keys %v values %v", key, keyList, valueList)
+
+	for i, k := range keyList {
+		logger.Infof("got children list key -> %s", k)
+		listener.DataChange(remoting.Event{
+			Path:    k,
+			Action:  remoting.EventTypeAdd,
+			Content: valueList[i],
+		})
+	}
+
+	logger.Infof("listen dubbo provider key{%s} event and wait to get all provider etcdv3 nodes", key)
+	go func(key string, listener remoting.DataListener) {
+		l.ListenServiceNodeEventWithPrefix(key, listener)
+		logger.Warnf("listenDirEvent(key{%s}) goroutine exit now", key)
+	}(key, listener)
+
+	logger.Infof("listen dubbo service key{%s}", key)
+	go func(key string) {
+		if l.ListenServiceNodeEvent(key) {
+			listener.DataChange(remoting.Event{Path: key, Action: remoting.EventTypeDel})
+		}
+		logger.Warnf("listenSelf(etcd key{%s}) goroutine exit now", key)
+	}(key)
+}
+
+func (l *EventListener) Close() {
+	l.wg.Wait()
+}
diff --git a/remoting/etcdv3/listener_test.go b/remoting/etcdv3/listener_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..33904a21345ec0ac7ee1adbb239a0a7a44852387
--- /dev/null
+++ b/remoting/etcdv3/listener_test.go
@@ -0,0 +1,87 @@
+package etcdv3
+
+import (
+	"time"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/apache/dubbo-go/remoting"
+)
+
+var changedData = `
+	dubbo.consumer.request_timeout=3s
+	dubbo.consumer.connect_timeout=5s
+	dubbo.application.organization=ikurento.com
+	dubbo.application.name=BDTService
+	dubbo.application.module=dubbogo user-info server
+	dubbo.application.version=0.0.1
+	dubbo.application.owner=ZX
+	dubbo.application.environment=dev
+	dubbo.registries.hangzhouzk.protocol=zookeeper
+	dubbo.registries.hangzhouzk.timeout=3s
+	dubbo.registries.hangzhouzk.address=127.0.0.1:2181
+	dubbo.registries.shanghaizk.protocol=zookeeper
+	dubbo.registries.shanghaizk.timeout=3s
+	dubbo.registries.shanghaizk.address=127.0.0.1:2182
+	dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo
+	dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider
+	dubbo.service.com.ikurento.user.UserProvider.loadbalance=random
+	dubbo.service.com.ikurento.user.UserProvider.warmup=100
+	dubbo.service.com.ikurento.user.UserProvider.cluster=failover
+`
+
+func (suite *ClientTestSuite) TestListener() {
+
+	var tests = []struct {
+		input struct {
+			k string
+			v string
+		}
+	}{
+		{input: struct {
+			k string
+			v string
+		}{k: "/dubbo", v: changedData}},
+	}
+
+	c := suite.client
+	t := suite.T()
+
+	listener := NewEventListener(c)
+	dataListener := &mockDataListener{client: c, changedData: changedData, rc: make(chan remoting.Event)}
+	listener.ListenServiceEvent("/dubbo", dataListener)
+
+	// NOTICE:  direct listen will lose create msg
+	time.Sleep(time.Second)
+	for _, tc := range tests {
+
+		k := tc.input.k
+		v := tc.input.v
+		if err := c.Create(k, v); err != nil {
+			t.Fatal(err)
+		}
+
+	}
+	msg := <-dataListener.rc
+	assert.Equal(t, changedData, msg.Content)
+}
+
+type mockDataListener struct {
+	eventList   []remoting.Event
+	client      *Client
+	changedData string
+
+	rc chan remoting.Event
+}
+
+func (m *mockDataListener) DataChange(eventType remoting.Event) bool {
+	m.eventList = append(m.eventList, eventType)
+	if eventType.Content == m.changedData {
+		m.rc <- eventType
+	}
+	return true
+}
diff --git a/remoting/listener.go b/remoting/listener.go
index 866c8503bb1c112db4182e31052199d49a25c7fd..b94ba26980b50db99e766fcc8febb07d6b554274 100644
--- a/remoting/listener.go
+++ b/remoting/listener.go
@@ -52,6 +52,7 @@ const (
 var serviceEventTypeStrings = [...]string{
 	"add",
 	"delete",
+	"update",
 }
 
 func (t EventType) String() string {
diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go
index d1d5f9900dbd67bbd061b411eaf2e40ffa0e7561..008848ea61ba2deb1a70aba5c29da097c3c48da9 100644
--- a/remoting/zookeeper/client.go
+++ b/remoting/zookeeper/client.go
@@ -125,7 +125,8 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error {
 				url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT), err.Error())
 			return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.Location)
 		}
-		newClient, err := newZookeeperClient(opions.zkName, []string{url.Location}, timeout)
+		zkAddresses := strings.Split(url.Location, ",")
+		newClient, err := newZookeeperClient(opions.zkName, zkAddresses, timeout)
 		if err != nil {
 			logger.Warnf("newZookeeperClient(name{%s}, zk addresss{%v}, timeout{%d}) = error{%v}",
 				opions.zkName, url.Location, timeout.String(), err)
@@ -298,29 +299,26 @@ func (z *ZookeeperClient) UnregisterEvent(zkPath string, event *chan struct{}) {
 	if zkPath == "" {
 		return
 	}
-
 	z.Lock()
-	for {
-		a, ok := z.eventRegistry[zkPath]
-		if !ok {
-			break
-		}
-		for i, e := range a {
-			if e == event {
-				arr := a
-				a = append(arr[:i], arr[i+1:]...)
-				logger.Debugf("zkClient{%s} unregister event{path:%s, event:%p}", z.name, zkPath, event)
-			}
-		}
-		logger.Debugf("after zkClient{%s} unregister event{path:%s, event:%p}, array length %d",
-			z.name, zkPath, event, len(a))
-		if len(a) == 0 {
-			delete(z.eventRegistry, zkPath)
-		} else {
-			z.eventRegistry[zkPath] = a
+	defer z.Unlock()
+	infoList, ok := z.eventRegistry[zkPath]
+	if !ok {
+		return
+	}
+	for i, e := range infoList {
+		if e == event {
+			arr := infoList
+			infoList = append(arr[:i], arr[i+1:]...)
+			logger.Infof("zkClient{%s} unregister event{path:%s, event:%p}", z.name, zkPath, event)
 		}
 	}
-	z.Unlock()
+	logger.Debugf("after zkClient{%s} unregister event{path:%s, event:%p}, array length %d",
+		z.name, zkPath, event, len(infoList))
+	if len(infoList) == 0 {
+		delete(z.eventRegistry, zkPath)
+	} else {
+		z.eventRegistry[zkPath] = infoList
+	}
 }
 
 func (z *ZookeeperClient) Done() <-chan struct{} {
diff --git a/remoting/zookeeper/facade.go b/remoting/zookeeper/facade.go
index 4fd800f87732288527d9387580fe70d0a9cae9d2..cdc7ead61226906a629fdb99b6b966ada5ee5253 100644
--- a/remoting/zookeeper/facade.go
+++ b/remoting/zookeeper/facade.go
@@ -19,9 +19,9 @@ package zookeeper
 
 import (
 	"sync"
-	"time"
 )
 import (
+	"github.com/dubbogo/getty"
 	perrors "github.com/pkg/errors"
 )
 
@@ -63,14 +63,14 @@ LOOP:
 			r.SetZkClient(nil)
 			r.ZkClientLock().Unlock()
 
-			// 接zk,直至成功
+			// Connect zk until success.
 			failTimes = 0
 			for {
 				select {
 				case <-r.GetDone():
 					logger.Warnf("(ZkProviderRegistry)reconnectZkRegistry goroutine exit now...")
 					break LOOP
-				case <-time.After(time.Duration(1e9 * failTimes * ConnDelay)): // 防止疯狂重连zk
+				case <-getty.GetTimeWheel().After(timeSecondDuration(failTimes * ConnDelay)): // Prevent crazy reconnection zk.
 				}
 				err = ValidateZookeeperClient(r, WithZkName(zkName))
 				logger.Infof("ZkProviderRegistry.validateZookeeperClient(zkAddr{%s}) = error{%#v}",
diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go
index 78c83ba3b249aae1e3f1059d64d718d0546b0d81..30347d494c14b989c43c2f3f4ea276b35d99f71b 100644
--- a/remoting/zookeeper/listener.go
+++ b/remoting/zookeeper/listener.go
@@ -24,6 +24,7 @@ import (
 )
 
 import (
+	"github.com/dubbogo/getty"
 	perrors "github.com/pkg/errors"
 	"github.com/samuel/go-zookeeper/zk"
 )
@@ -129,14 +130,14 @@ func (l *ZkEventListener) handleZkNodeEvent(zkPath string, children []string, li
 			continue
 		}
 		// listen l service node
-		go func(node, childNode string) {
+		go func(node string) {
 			logger.Infof("delete zkNode{%s}", node)
 			if l.ListenServiceNodeEvent(node, listener) {
-				logger.Infof("delete content{%s}", childNode)
+				logger.Infof("delete content{%s}", node)
 				listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel})
 			}
 			logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath)
-		}(newNode, n)
+		}(newNode)
 	}
 
 	// old node was deleted
@@ -188,7 +189,7 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi
 			}
 			l.client.RegisterEvent(zkPath, &event)
 			select {
-			case <-time.After(timeSecondDuration(failTimes * ConnDelay)):
+			case <-getty.GetTimeWheel().After(timeSecondDuration(failTimes * ConnDelay)):
 				l.client.UnregisterEvent(zkPath, &event)
 				continue
 			case <-l.client.Done():
@@ -207,6 +208,20 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi
 
 			// listen l service node
 			dubboPath := path.Join(zkPath, c)
+
+			//Save the path to avoid listen repeatly
+			l.pathMapLock.Lock()
+			_, ok := l.pathMap[dubboPath]
+			l.pathMapLock.Unlock()
+			if ok {
+				logger.Warnf("@zkPath %s has already been listened.", zkPath)
+				continue
+			}
+
+			l.pathMapLock.Lock()
+			l.pathMap[dubboPath] = struct{}{}
+			l.pathMapLock.Unlock()
+
 			content, _, err := l.client.Conn.Get(dubboPath)
 			if err != nil {
 				logger.Errorf("Get new node path {%v} 's content error,message is  {%v}", dubboPath, perrors.WithStack(err))
diff --git a/remoting/zookeeper/listener_test.go b/remoting/zookeeper/listener_test.go
index c2fedb911b7560a13c5b98d865cb97575a7719df..a90fbad05ae787f36d38607b0a73374d874e6994 100644
--- a/remoting/zookeeper/listener_test.go
+++ b/remoting/zookeeper/listener_test.go
@@ -118,6 +118,7 @@ func (m *mockDataListener) DataChange(eventType remoting.Event) bool {
 	if eventType.Content == m.changedData {
 		m.wait.Done()
 		m.client.Close()
+
 	}
 	return true
 }
diff --git a/remoting/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar b/remoting/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar
deleted file mode 100644
index 839531b8b8762a9c19e334a5cbf79314cb16f945..0000000000000000000000000000000000000000
Binary files a/remoting/zookeeper/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar and /dev/null differ