diff --git a/.scannerwork/.sonar_lock b/.scannerwork/.sonar_lock
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/.scannerwork/report-task.txt b/.scannerwork/report-task.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e103b179c47886125f4ff52cb931b319eeced906
--- /dev/null
+++ b/.scannerwork/report-task.txt
@@ -0,0 +1,6 @@
+projectKey=dubbo-go
+serverUrl=http://10.5.93.51:9000
+serverVersion=7.2.1.14109
+dashboardUrl=http://10.5.93.51:9000/dashboard?id=dubbo-go
+ceTaskId=AWq7jn_CCGPI4YFoFYV9
+ceTaskUrl=http://10.5.93.51:9000/api/ce/task?id=AWq7jn_CCGPI4YFoFYV9
diff --git a/.scannerwork/uast-generator-go-linux-amd64 b/.scannerwork/uast-generator-go-linux-amd64
new file mode 100644
index 0000000000000000000000000000000000000000..5818bde72e5009c9f781e71dba2263e886b0bc59
Binary files /dev/null and b/.scannerwork/uast-generator-go-linux-amd64 differ
diff --git a/protocol/jsonrpc/http_test.go b/protocol/jsonrpc/http_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8c681e8d06ce978ead14624604b1d5916ae4f20d
--- /dev/null
+++ b/protocol/jsonrpc/http_test.go
@@ -0,0 +1,99 @@
+package jsonrpc
+
+import (
+	"context"
+	"errors"
+	"strings"
+	"testing"
+	"time"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/dubbo/go-for-apache-dubbo/common"
+	"github.com/dubbo/go-for-apache-dubbo/common/constant"
+	"github.com/dubbo/go-for-apache-dubbo/protocol"
+)
+
+type (
+	User struct {
+		Id   string `json:"id"`
+		Name string `json:"name"`
+	}
+
+	UserProvider struct {
+		user map[string]User
+	}
+)
+
+func TestHTTPClient_Call(t *testing.T) {
+
+	methods, err := common.ServiceMap.Register("jsonrpc", &UserProvider{})
+	assert.NoError(t, err)
+	assert.Equal(t, "GetUser,GetUser1", methods)
+
+	// Export
+	proto := GetProtocol()
+	url, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20000/com.ikurento.user.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")
+	assert.NoError(t, err)
+	proto.Export(protocol.NewBaseInvoker(url))
+
+	client := NewHTTPClient(&HTTPOptions{
+		HandshakeTimeout: time.Second,
+		HTTPTimeout:      time.Second,
+	})
+
+	// call GetUser
+	ctx := context.WithValue(context.Background(), constant.DUBBOGO_CTX_KEY, map[string]string{
+		"X-Proxy-Id": "dubbogo",
+		"X-Services": url.Path,
+		"X-Method":   "GetUser",
+	})
+	req := client.NewRequest(url, "GetUser", []interface{}{"1", "username"})
+	reply := &User{}
+	err = client.Call(ctx, url, req, reply)
+	assert.NoError(t, err)
+	assert.Equal(t, "1", reply.Id)
+	assert.Equal(t, "username", reply.Name)
+
+	// call GetUser1
+	ctx = context.WithValue(context.Background(), constant.DUBBOGO_CTX_KEY, map[string]string{
+		"X-Proxy-Id": "dubbogo",
+		"X-Services": url.Path,
+		"X-Method":   "GetUser1",
+	})
+	req = client.NewRequest(url, "GetUser1", []interface{}{""})
+	reply = &User{}
+	err = client.Call(ctx, url, req, reply)
+	assert.True(t, strings.Contains(err.Error(), "500 Internal Server Error"))
+	assert.True(t, strings.Contains(err.Error(), "\\\"result\\\":{},\\\"error\\\":{\\\"code\\\":-32000,\\\"message\\\":\\\"error\\\"}"))
+
+	// destroy
+	proto.Destroy()
+
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	rsp.Id = req[0].(string)
+	rsp.Name = req[1].(string)
+	return nil
+}
+
+func (u *UserProvider) GetUser1(ctx context.Context, req []interface{}, rsp *User) error {
+	return errors.New("error")
+}
+
+func (u *UserProvider) Service() string {
+	return "com.ikurento.user.UserProvider"
+}
+
+func (u *UserProvider) Version() string {
+	return ""
+}
diff --git a/protocol/jsonrpc/json_test.go b/protocol/jsonrpc/json_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b14afe7778a626fdeeeb71916ff8a51613a38258
--- /dev/null
+++ b/protocol/jsonrpc/json_test.go
@@ -0,0 +1,70 @@
+package jsonrpc
+
+import (
+	"encoding/json"
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+type TestData struct {
+	Test string
+}
+
+func TestJsonClientCodec_Write(t *testing.T) {
+	cd := &CodecData{
+		ID:     1,
+		Method: "GetUser",
+		Args:   []interface{}{"args", 2},
+	}
+	codec := newJsonClientCodec()
+	data, err := codec.Write(cd)
+	assert.NoError(t, err)
+	assert.Equal(t, "{\"jsonrpc\":\"2.0\",\"method\":\"GetUser\",\"params\":[\"args\",2],\"id\":1}\n", string(data))
+}
+
+func TestJsonClientCodec_Read(t *testing.T) {
+	codec := newJsonClientCodec()
+	codec.pending[1] = "GetUser"
+	rsp := &TestData{}
+	err := codec.Read([]byte("{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"Test\":\"test\"}}\n"), rsp)
+	assert.NoError(t, err)
+	assert.Equal(t, "test", rsp.Test)
+
+	//error
+	codec.pending[1] = "GetUser"
+	err = codec.Read([]byte("{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32000,\"message\":\"error\"}}\n"), rsp)
+	assert.EqualError(t, err, "{\"code\":-32000,\"message\":\"error\"}")
+}
+
+func TestServerCodec_Write(t *testing.T) {
+	codec := newServerCodec()
+	a := json.RawMessage([]byte("1"))
+	codec.req = serverRequest{Version: "1.0", Method: "GetUser", ID: &a}
+	data, err := codec.Write("error", &TestData{Test: "test"})
+	assert.NoError(t, err)
+	assert.Equal(t, "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"Test\":\"test\"},\"error\":{\"code\":-32000,\"message\":\"error\"}}\n", string(data))
+}
+
+func TestServerCodec_Read(t *testing.T) {
+	codec := newServerCodec()
+	header := map[string]string{}
+	err := codec.ReadHeader(header, []byte("{\"jsonrpc\":\"2.0\",\"method\":\"GetUser\",\"params\":[\"args\",2],\"id\":1}\n"))
+	assert.EqualError(t, err, "{\"code\":-32601,\"message\":\"Method not found\"}")
+
+	header["HttpMethod"] = "POST"
+	err = codec.ReadHeader(header, []byte("{\"jsonrpc\":\"2.0\",\"method\":\"GetUser\",\"params\":[\"args\",2],\"id\":1}\n"))
+	assert.NoError(t, err)
+	assert.Equal(t, "1", string([]byte(*codec.req.ID)))
+	assert.Equal(t, "GetUser", codec.req.Method)
+	assert.Equal(t, "2.0", codec.req.Version)
+	assert.Equal(t, "[\"args\",2]", string([]byte(*codec.req.Params)))
+
+	req := []interface{}{}
+	err = codec.ReadBody(&req)
+	assert.NoError(t, err)
+	assert.Equal(t, "args", req[0])
+	assert.Equal(t, float64(2), req[1])
+}
diff --git a/protocol/jsonrpc/jsonrpc_protocol_test.go b/protocol/jsonrpc/jsonrpc_protocol_test.go
index e8609da1ab8e94f35ba44abc85b44d1645c074e5..f67a5d8ed93decb336b84f956a0bcbc9a4228a90 100644
--- a/protocol/jsonrpc/jsonrpc_protocol_test.go
+++ b/protocol/jsonrpc/jsonrpc_protocol_test.go
@@ -19,7 +19,7 @@ import (
 func TestJsonrpcProtocol_Export(t *testing.T) {
 	// 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(), "jsonrpc://127.0.0.1:20000/com.ikurento.user.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&"+
@@ -49,7 +49,7 @@ func TestJsonrpcProtocol_Export(t *testing.T) {
 func TestJsonrpcProtocol_Refer(t *testing.T) {
 	// Refer
 	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(), "jsonrpc://127.0.0.1:20000/com.ikurento.user.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&"+
diff --git a/registry/zookeeper/zk_client.go b/registry/zookeeper/zk_client.go
index cb417729e30154b6ba2aaadd33c313d0683d5282..d8d351fbdadf61ed80a363567224cb032271203f 100644
--- a/registry/zookeeper/zk_client.go
+++ b/registry/zookeeper/zk_client.go
@@ -220,7 +220,6 @@ func (z *zookeeperClient) unregisterEvent(zkPath string, event *chan struct{}) {
 		} else {
 			z.eventRegistry[zkPath] = a
 		}
-		break
 	}
 	z.Unlock()
 }
diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6d358a3704e97d6e801aec6bce70fad639be7fa9
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,12 @@
+sonar.projectKey=dubbo-go
+sonar.projectName=dubbo-go
+sonar.host.url=http://10.5.93.51:9000
+sonar.sourceEncoding=UTF-8
+sonar.sources=.
+sonar.exclusions=**/*_test.go,examples/**
+
+sonar.tests=.
+sonar.test.inclusions=**/*_test.go
+sonar.test.exclusions=examples/**
+
+sonar.go.coverage.reportPaths=./coverage.out