You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by il...@apache.org on 2020/11/02 09:51:12 UTC

[dubbo-go-samples] branch makefile updated: make integration test work for registry/etcd

This is an automated email from the ASF dual-hosted git repository.

iluo pushed a commit to branch makefile
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git


The following commit(s) were added to refs/heads/makefile by this push:
     new e6e7b14  make integration test work for registry/etcd
e6e7b14 is described below

commit e6e7b144876696f0aa2a49209ae18854b60d1247
Author: Ian Luo <ia...@gmail.com>
AuthorDate: Mon Nov 2 17:50:44 2020 +0800

    make integration test work for registry/etcd
---
 build/Makefile                                     |   2 +
 registry/etcd/go-client/app/client.go              |  77 ---------
 registry/etcd/go-client/app/user.go                |  37 -----
 registry/etcd/go-client/app/version.go             |   5 -
 registry/etcd/go-client/assembly/bin/load.sh       | 184 ---------------------
 .../etcd/go-client/assembly/common/app.properties  |   6 -
 registry/etcd/go-client/assembly/common/build.sh   |  65 --------
 registry/etcd/go-client/assembly/mac/dev.sh        |  17 --
 registry/etcd/go-client/cmd/client.go              |  65 ++++++++
 .../go-client/{profiles/dev => conf}/client.yml    |  35 ++--
 .../profiles/dev => go-client/conf}/log.yml        |   4 +-
 registry/etcd/go-client/pkg/user.go                |  42 +++++
 registry/etcd/go-server/app/user.go                |  46 ------
 registry/etcd/go-server/app/version.go             |   5 -
 registry/etcd/go-server/assembly/bin/load.sh       | 132 ---------------
 .../etcd/go-server/assembly/common/app.properties  |   6 -
 registry/etcd/go-server/assembly/common/build.sh   |  62 -------
 registry/etcd/go-server/assembly/mac/dev.sh        |  17 --
 registry/etcd/go-server/assembly/mac/release.sh    |  18 --
 registry/etcd/go-server/assembly/mac/test.sh       |  17 --
 registry/etcd/go-server/{app => cmd}/server.go     |  42 +++--
 .../profiles/dev => go-server/conf}/client.yml     |  35 ++--
 .../profiles/dev => go-server/conf}/log.yml        |   5 +-
 .../go-server/{profiles/dev => conf}/server.yml    |  28 ++--
 registry/etcd/go-server/docker/docker-compose.yml  |  21 +++
 registry/etcd/go-server/pkg/user.go                |  63 +++++++
 .../etcd/go-server/tests/integration/main_test.go  |  70 ++++++++
 .../tests/integration/userprovider_test.go         |  38 +++++
 28 files changed, 379 insertions(+), 765 deletions(-)

diff --git a/build/Makefile b/build/Makefile
index 97f2771..50ad75c 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -28,6 +28,8 @@ export GOPROXY ?= https://goproxy.io,direct
 export GOSUMDB ?= sum.golang.org
 export GOARCH ?= amd64
 
+export DOCKER_HOST_IP = $(shell ifconfig en0 | grep inet | grep -v inet6 | awk '{print $$2}')
+
 OS := $(shell uname)
 ifeq ($(OS), Linux)
 	export GOOS ?= linux
diff --git a/registry/etcd/go-client/app/client.go b/registry/etcd/go-client/app/client.go
deleted file mode 100644
index df52b1f..0000000
--- a/registry/etcd/go-client/app/client.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package main
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"os/signal"
-	"syscall"
-	"time"
-)
-
-import (
-	"github.com/dubbogo/gost/log"
-)
-
-import (
-	hessian "github.com/apache/dubbo-go-hessian2"
-	"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/filter_impl"
-
-	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
-	_ "github.com/apache/dubbo-go/cluster/loadbalance"
-
-	// import etcdv3 to init etcdv3 registry
-	_ "github.com/apache/dubbo-go/registry/etcdv3"
-)
-
-var (
-	survivalTimeout int = 10e9
-)
-
-// they are necessary:
-// 		export CONF_CONSUMER_FILE_PATH="xxx"
-// 		export APP_LOG_CONF_FILE="xxx"
-func main() {
-	hessian.RegisterPOJO(&User{})
-	config.Load()
-	time.Sleep(3e9)
-
-	gxlog.CInfo("\n\n\nstart to test dubbo")
-	user := &User{}
-	err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user)
-	if err != nil {
-		panic(err)
-	}
-	gxlog.CInfo("response result: %v\n", user)
-	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:
-			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
-		}
-	}
-}
diff --git a/registry/etcd/go-client/app/user.go b/registry/etcd/go-client/app/user.go
deleted file mode 100644
index da98c72..0000000
--- a/registry/etcd/go-client/app/user.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package main
-
-import (
-	"context"
-	"time"
-)
-
-import (
-	hessian "github.com/apache/dubbo-go-hessian2"
-	"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/registry/etcd/go-client/app/version.go b/registry/etcd/go-client/app/version.go
deleted file mode 100644
index 2ecc5fa..0000000
--- a/registry/etcd/go-client/app/version.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package main
-
-var (
-	Version = "2.7.5"
-)
diff --git a/registry/etcd/go-client/assembly/bin/load.sh b/registry/etcd/go-client/assembly/bin/load.sh
deleted file mode 100644
index 598bbcb..0000000
--- a/registry/etcd/go-client/assembly/bin/load.sh
+++ /dev/null
@@ -1,184 +0,0 @@
-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
\ No newline at end of file
diff --git a/registry/etcd/go-client/assembly/common/app.properties b/registry/etcd/go-client/assembly/common/app.properties
deleted file mode 100644
index 5708ca9..0000000
--- a/registry/etcd/go-client/assembly/common/app.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-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"
\ No newline at end of file
diff --git a/registry/etcd/go-client/assembly/common/build.sh b/registry/etcd/go-client/assembly/common/build.sh
deleted file mode 100644
index 2afbb49..0000000
--- a/registry/etcd/go-client/assembly/common/build.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-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 GO111MODULE=on 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 GO111MODULE=on 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}/*
\ No newline at end of file
diff --git a/registry/etcd/go-client/assembly/mac/dev.sh b/registry/etcd/go-client/assembly/mac/dev.sh
deleted file mode 100644
index d242789..0000000
--- a/registry/etcd/go-client/assembly/mac/dev.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-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
\ No newline at end of file
diff --git a/registry/etcd/go-client/cmd/client.go b/registry/etcd/go-client/cmd/client.go
new file mode 100644
index 0000000..e0e9f38
--- /dev/null
+++ b/registry/etcd/go-client/cmd/client.go
@@ -0,0 +1,65 @@
+/*
+ * 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"
+	"os"
+	"time"
+)
+
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+	"github.com/apache/dubbo-samples/golang/registry/etcd/go-client/pkg"
+	"github.com/dubbogo/gost/log"
+)
+
+import (
+	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
+	_ "github.com/apache/dubbo-go/cluster/loadbalance"
+	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+	"github.com/apache/dubbo-go/config"
+	_ "github.com/apache/dubbo-go/filter/filter_impl"
+	_ "github.com/apache/dubbo-go/protocol/dubbo"
+	_ "github.com/apache/dubbo-go/registry/etcdv3"
+	_ "github.com/apache/dubbo-go/registry/protocol"
+)
+
+var userProvider = new(pkg.UserProvider)
+
+func init() {
+	config.SetConsumerService(userProvider)
+	hessian.RegisterPOJO(&pkg.User{})
+}
+
+// need to setup environment variable "CONF_CONSUMER_FILE_PATH" to "conf/client.yml" before run
+func main() {
+	hessian.RegisterPOJO(&pkg.User{})
+	config.Load()
+	time.Sleep(3 * time.Second)
+
+	gxlog.CInfo("\n\n\nstart to test dubbo")
+	user := &pkg.User{}
+	err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user)
+	if err != nil {
+		gxlog.CError("error: %v\n", err)
+		os.Exit(1)
+		return
+	}
+	gxlog.CInfo("response result: %v\n", user)
+}
diff --git a/registry/etcd/go-client/profiles/dev/client.yml b/registry/etcd/go-client/conf/client.yml
similarity index 67%
copy from registry/etcd/go-client/profiles/dev/client.yml
copy to registry/etcd/go-client/conf/client.yml
index f3b4b17..e514c2e 100644
--- a/registry/etcd/go-client/profiles/dev/client.yml
+++ b/registry/etcd/go-client/conf/client.yml
@@ -1,41 +1,40 @@
 # dubbo client yaml configure file
 
-
 check: true
 # client
-request_timeout : "3s"
+request_timeout: "3s"
 # connect timeout
-connect_timeout : "3s"
+connect_timeout: "3s"
 
 # application config
 application:
-  organization : "ikurento.com"
-  name  : "BDTService"
-  module : "dubbogo user-info client"
-  version : "0.0.1"
-  owner : "ZX"
-  environment : "dev"
-
-registries :
+  organization: "dubbo.io"
+  name: "UserInfoClient"
+  module: "dubbo-go user-info client"
+  version: "0.0.1"
+  environment: "dev"
+
+# registry config
+registries:
   "etcd":
     protocol: "etcdv3"
-    timeout	: "3s"
+    timeout: "3s"
     address: "127.0.0.1:2379"
     username: ""
     password: ""
 
-
+# reference config
 references:
   "UserProvider":
-    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-    protocol : "dubbo"
-    interface : "com.ikurento.user.UserProvider"
+    registry: "etcd"
+    protocol: "dubbo"
+    interface: "org.apache.dubbo.UserProvider"
     cluster: "failover"
-    methods :
+    methods:
       - name: "GetUser"
         retries: 3
 
-
+# protocol config
 protocol_conf:
   dubbo:
     reconnect_interval: 0
diff --git a/registry/etcd/go-server/profiles/dev/log.yml b/registry/etcd/go-client/conf/log.yml
similarity index 90%
rename from registry/etcd/go-server/profiles/dev/log.yml
rename to registry/etcd/go-client/conf/log.yml
index ed4d3cb..2b6e93a 100644
--- a/registry/etcd/go-server/profiles/dev/log.yml
+++ b/registry/etcd/go-client/conf/log.yml
@@ -14,7 +14,7 @@ encoderConfig:
   callerKey: "caller"
   stacktraceKey: "stacktrace"
   lineEnding: ""
-  levelEncoder: "capitalColor"
+  levelEncoder: "capital"
   timeEncoder: "iso8601"
   durationEncoder: "seconds"
   callerEncoder: "short"
@@ -24,4 +24,4 @@ outputPaths:
   - "stderr"
 errorOutputPaths:
   - "stderr"
-initialFields:
\ No newline at end of file
+initialFields:
diff --git a/registry/etcd/go-client/pkg/user.go b/registry/etcd/go-client/pkg/user.go
new file mode 100644
index 0000000..75c964f
--- /dev/null
+++ b/registry/etcd/go-client/pkg/user.go
@@ -0,0 +1,42 @@
+/*
+ * 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 pkg
+
+import (
+	"context"
+	"time"
+)
+
+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 "org.apache.dubbo.User"
+}
diff --git a/registry/etcd/go-server/app/user.go b/registry/etcd/go-server/app/user.go
deleted file mode 100644
index d146aa0..0000000
--- a/registry/etcd/go-server/app/user.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package main
-
-import (
-	"context"
-	"time"
-)
-
-import (
-	"github.com/dubbogo/gost/log"
-)
-
-import (
-	hessian "github.com/apache/dubbo-go-hessian2"
-	"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) {
-	gxlog.CInfo("req:%#v", req)
-	rsp := User{"A001", "Alex Stocks", 18, time.Now()}
-	gxlog.CInfo("rsp:%#v", rsp)
-	return &rsp, nil
-}
-
-func (u *UserProvider) Reference() string {
-	return "UserProvider"
-}
-
-func (u User) JavaClassName() string {
-	return "com.ikurento.user.User"
-}
diff --git a/registry/etcd/go-server/app/version.go b/registry/etcd/go-server/app/version.go
deleted file mode 100644
index 2ecc5fa..0000000
--- a/registry/etcd/go-server/app/version.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package main
-
-var (
-	Version = "2.7.5"
-)
diff --git a/registry/etcd/go-server/assembly/bin/load.sh b/registry/etcd/go-server/assembly/bin/load.sh
deleted file mode 100644
index d247297..0000000
--- a/registry/etcd/go-server/assembly/bin/load.sh
+++ /dev/null
@@ -1,132 +0,0 @@
-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
\ No newline at end of file
diff --git a/registry/etcd/go-server/assembly/common/app.properties b/registry/etcd/go-server/assembly/common/app.properties
deleted file mode 100644
index 8e0d12b..0000000
--- a/registry/etcd/go-server/assembly/common/app.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-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"
\ No newline at end of file
diff --git a/registry/etcd/go-server/assembly/common/build.sh b/registry/etcd/go-server/assembly/common/build.sh
deleted file mode 100644
index 9b09954..0000000
--- a/registry/etcd/go-server/assembly/common/build.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-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} && GO111MODULE=on 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} && GO111MODULE=on 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}/*
\ No newline at end of file
diff --git a/registry/etcd/go-server/assembly/mac/dev.sh b/registry/etcd/go-server/assembly/mac/dev.sh
deleted file mode 100644
index b1bca8b..0000000
--- a/registry/etcd/go-server/assembly/mac/dev.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-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
\ No newline at end of file
diff --git a/registry/etcd/go-server/assembly/mac/release.sh b/registry/etcd/go-server/assembly/mac/release.sh
deleted file mode 100644
index 9fa8786..0000000
--- a/registry/etcd/go-server/assembly/mac/release.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-
-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
\ No newline at end of file
diff --git a/registry/etcd/go-server/assembly/mac/test.sh b/registry/etcd/go-server/assembly/mac/test.sh
deleted file mode 100644
index 83e2d15..0000000
--- a/registry/etcd/go-server/assembly/mac/test.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-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
\ No newline at end of file
diff --git a/registry/etcd/go-server/app/server.go b/registry/etcd/go-server/cmd/server.go
similarity index 55%
rename from registry/etcd/go-server/app/server.go
rename to registry/etcd/go-server/cmd/server.go
index 0a85fa2..2ef1c83 100644
--- a/registry/etcd/go-server/app/server.go
+++ b/registry/etcd/go-server/cmd/server.go
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package main
 
 import (
@@ -7,36 +24,31 @@ import (
 	"syscall"
 	"time"
 )
+
 import (
 	hessian "github.com/apache/dubbo-go-hessian2"
-	"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/filter_impl"
+	"github.com/apache/dubbo-samples/golang/registry/etcd/go-server/pkg"
 
 	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
 	_ "github.com/apache/dubbo-go/cluster/loadbalance"
-
-	// import etcdv3 to init etcdv3 registry
+	"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/filter/filter_impl"
+	_ "github.com/apache/dubbo-go/protocol/dubbo"
 	_ "github.com/apache/dubbo-go/registry/etcdv3"
+	_ "github.com/apache/dubbo-go/registry/protocol"
 )
 
 var (
 	survivalTimeout = int(3e9)
 )
 
-// they are necessary:
-// 		export CONF_PROVIDER_FILE_PATH="xxx"
-// 		export APP_LOG_CONF_FILE="xxx"
+// need to setup environment variable "CONF_PROVIDER_FILE_PATH" to "conf/server.yml" before run
 func main() {
-
-	hessian.RegisterPOJO(&User{})
+	hessian.RegisterPOJO(&pkg.User{})
 	config.Load()
 
-	logger.Info("xxx")
 	initSignal()
 }
 
diff --git a/registry/etcd/go-client/profiles/dev/client.yml b/registry/etcd/go-server/conf/client.yml
similarity index 67%
rename from registry/etcd/go-client/profiles/dev/client.yml
rename to registry/etcd/go-server/conf/client.yml
index f3b4b17..0832a89 100644
--- a/registry/etcd/go-client/profiles/dev/client.yml
+++ b/registry/etcd/go-server/conf/client.yml
@@ -1,41 +1,40 @@
 # dubbo client yaml configure file
 
-
 check: true
 # client
-request_timeout : "3s"
+request_timeout: "3s"
 # connect timeout
-connect_timeout : "3s"
+connect_timeout: "3s"
 
 # application config
 application:
-  organization : "ikurento.com"
-  name  : "BDTService"
-  module : "dubbogo user-info client"
-  version : "0.0.1"
-  owner : "ZX"
-  environment : "dev"
-
-registries :
+  organization: "dubbo.io"
+  name: "UserInfoTest"
+  module: "dubbo-go user-info client"
+  version: "0.0.1"
+  environment: "dev"
+
+# registry config
+registries:
   "etcd":
     protocol: "etcdv3"
-    timeout	: "3s"
+    timeout: "3s"
     address: "127.0.0.1:2379"
     username: ""
     password: ""
 
-
+# reference config
 references:
   "UserProvider":
-    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
-    protocol : "dubbo"
-    interface : "com.ikurento.user.UserProvider"
+    registry: "etcd"
+    protocol: "dubbo"
+    interface: "org.apache.dubbo.UserProvider"
     cluster: "failover"
-    methods :
+    methods:
       - name: "GetUser"
         retries: 3
 
-
+# protocol config
 protocol_conf:
   dubbo:
     reconnect_interval: 0
diff --git a/registry/etcd/go-client/profiles/dev/log.yml b/registry/etcd/go-server/conf/log.yml
similarity index 90%
rename from registry/etcd/go-client/profiles/dev/log.yml
rename to registry/etcd/go-server/conf/log.yml
index 1d68ea3..2b6e93a 100644
--- a/registry/etcd/go-client/profiles/dev/log.yml
+++ b/registry/etcd/go-server/conf/log.yml
@@ -1,4 +1,3 @@
-
 level: "debug"
 development: true
 disableCaller: false
@@ -15,7 +14,7 @@ encoderConfig:
   callerKey: "caller"
   stacktraceKey: "stacktrace"
   lineEnding: ""
-  levelEncoder: "capitalColor"
+  levelEncoder: "capital"
   timeEncoder: "iso8601"
   durationEncoder: "seconds"
   callerEncoder: "short"
@@ -25,4 +24,4 @@ outputPaths:
   - "stderr"
 errorOutputPaths:
   - "stderr"
-initialFields:
\ No newline at end of file
+initialFields:
diff --git a/registry/etcd/go-server/profiles/dev/server.yml b/registry/etcd/go-server/conf/server.yml
similarity index 66%
rename from registry/etcd/go-server/profiles/dev/server.yml
rename to registry/etcd/go-server/conf/server.yml
index cd78586..3099fd2 100644
--- a/registry/etcd/go-server/profiles/dev/server.yml
+++ b/registry/etcd/go-server/conf/server.yml
@@ -1,28 +1,26 @@
 # dubbo server yaml configure file
 
-
 # application config
 application:
-  organization : "ikurento.com"
-  name : "BDTService"
-  module : "dubbogo user-info server"
-  version : "0.0.1"
-  owner : "ZX"
-  environment : "dev"
+  organization: "dubbo.io"
+  name: "UserInfoServer"
+  module: "dubbo-go user-info server"
+  version: "0.0.1"
+  environment: "dev"
 
-registries :
+# registry config
+registries:
   "etcd":
     protocol: "etcdv3"
-    timeout	: "3s"
+    timeout: "3s"
     address: "127.0.0.1:2379"
 
+# service config
 services:
   "UserProvider":
-    # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
     registry: "etcd"
-    protocol : "dubbo"
-    # 相当于dubbo.xml中的interface
-    interface : "com.ikurento.user.UserProvider"
+    protocol: "dubbo"
+    interface: "org.apache.dubbo.UserProvider"
     loadbalance: "random"
     warmup: "100"
     cluster: "failover"
@@ -31,12 +29,12 @@ services:
         retries: 1
         loadbalance: "random"
 
+# protocol config
 protocols:
   "dubbo":
     name: "dubbo"
     port: 20000
 
-
 protocol_conf:
   dubbo:
     session_number: 700
@@ -54,4 +52,4 @@ protocol_conf:
       tcp_write_timeout: "5s"
       wait_timeout: "1s"
       max_msg_len: 1024000
-      session_name: "server"
\ No newline at end of file
+      session_name: "server"
diff --git a/registry/etcd/go-server/docker/docker-compose.yml b/registry/etcd/go-server/docker/docker-compose.yml
new file mode 100644
index 0000000..18c9d27
--- /dev/null
+++ b/registry/etcd/go-server/docker/docker-compose.yml
@@ -0,0 +1,21 @@
+version: '3'
+
+services:
+  etcd:
+    image: "quay.io/coreos/etcd:latest"
+    container_name: etcd
+    environment:
+      - ETCDCTL_API=3
+    command: [
+        "etcd",
+        "--name=etcd0",
+        "--advertise-client-urls=http://${DOCKER_HOST_IP}:2379",
+        "--listen-client-urls=http://0.0.0.0:2379",
+        "--initial-advertise-peer-urls=http://${DOCKER_HOST_IP}:2380",
+        "--listen-peer-urls=http://0.0.0.0:2380",
+        "--initial-cluster=etcd0=http://${DOCKER_HOST_IP}:2380",
+    ]
+    ports:
+      - "2379:2379"
+      - "2380:2380"
+    restart: always
diff --git a/registry/etcd/go-server/pkg/user.go b/registry/etcd/go-server/pkg/user.go
new file mode 100644
index 0000000..37fcb25
--- /dev/null
+++ b/registry/etcd/go-server/pkg/user.go
@@ -0,0 +1,63 @@
+/*
+ * 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 pkg
+
+import (
+	"context"
+	"time"
+)
+
+import (
+	"github.com/dubbogo/gost/log"
+)
+
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+	"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) {
+	gxlog.CInfo("req:%#v", req)
+	rsp := User{"A001", "Alex Stocks", 18, time.Now()}
+	gxlog.CInfo("rsp:%#v", rsp)
+	return &rsp, nil
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+func (u User) JavaClassName() string {
+	return "org.apache.dubbo.User"
+}
diff --git a/registry/etcd/go-server/tests/integration/main_test.go b/registry/etcd/go-server/tests/integration/main_test.go
new file mode 100644
index 0000000..b813c03
--- /dev/null
+++ b/registry/etcd/go-server/tests/integration/main_test.go
@@ -0,0 +1,70 @@
+// +build integration
+
+/*
+ * 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 integration
+
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+	"github.com/apache/dubbo-go/config"
+
+	_ "github.com/apache/dubbo-go/cluster/cluster_impl"
+	_ "github.com/apache/dubbo-go/cluster/loadbalance"
+	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+	_ "github.com/apache/dubbo-go/filter/filter_impl"
+	_ "github.com/apache/dubbo-go/protocol/dubbo"
+	_ "github.com/apache/dubbo-go/registry/etcdv3"
+	_ "github.com/apache/dubbo-go/registry/protocol"
+)
+
+import (
+	"context"
+	"os"
+	"testing"
+	"time"
+)
+
+var userProvider = new(UserProvider)
+
+func TestMain(m *testing.M) {
+	config.SetConsumerService(userProvider)
+	hessian.RegisterPOJO(&User{})
+	config.Load()
+	time.Sleep(3 * time.Second)
+
+	os.Exit(m.Run())
+}
+
+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 "org.apache.dubbo.User"
+}
diff --git a/registry/etcd/go-server/tests/integration/userprovider_test.go b/registry/etcd/go-server/tests/integration/userprovider_test.go
new file mode 100644
index 0000000..09b09c3
--- /dev/null
+++ b/registry/etcd/go-server/tests/integration/userprovider_test.go
@@ -0,0 +1,38 @@
+// +build integration
+
+/*
+ * 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 integration
+
+import (
+	"context"
+	"testing"
+)
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGetUser(t *testing.T) {
+	user := &User{}
+	err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user)
+	assert.Nil(t, err)
+	assert.Equal(t, "A001", user.Id)
+	assert.Equal(t, "Alex Stocks", user.Name)
+	assert.Equal(t, int32(18), user.Age)
+	assert.NotNil(t, user.Time)
+}