diff --git a/config/rpc_service.go b/config/rpc_service.go
index 3d1e0482fb95f00ff7963f5e2fe5e2e449c8d6bf..3a627177e7be1cc52f16e2863f19212dd91da9a3 100644
--- a/config/rpc_service.go
+++ b/config/rpc_service.go
@@ -26,7 +26,7 @@ var (
 	typeOfError = reflect.TypeOf((*error)(nil)).Elem()
 
 	ServiceMap = &serviceMap{
-		serviceMap: make(map[string]*Service),
+		serviceMap: make(map[string]map[string]*Service),
 	}
 )
 
@@ -87,24 +87,28 @@ func (s *Service) Rcvr() reflect.Value {
 //////////////////////////
 
 type serviceMap struct {
-	mutex      sync.RWMutex        // protects the serviceMap
-	serviceMap map[string]*Service // service name -> service
+	mutex      sync.RWMutex                   // protects the serviceMap
+	serviceMap map[string]map[string]*Service // protocol -> service name -> service
 }
 
-func (sm *serviceMap) GetService(name string) *Service {
+func (sm *serviceMap) GetService(protocol, name string) *Service {
 	sm.mutex.RLock()
 	defer sm.mutex.RUnlock()
-	if s, ok := sm.serviceMap[name]; ok {
-		return s
+	if s, ok := sm.serviceMap[protocol]; ok {
+		if srv, ok := s[name]; ok {
+			return srv
+		}
+		return nil
 	}
 	return nil
 }
 
-func (sm *serviceMap) Register(rcvr RPCService) (string, error) {
+// todo:Register is called by 'ServiceConfig'
+func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error) {
 	sm.mutex.Lock()
 	defer sm.mutex.Unlock()
-	if sm.serviceMap == nil {
-		sm.serviceMap = make(map[string]*Service)
+	if sm.serviceMap[protocol] == nil {
+		sm.serviceMap[protocol] = make(map[string]*Service)
 	}
 
 	s := new(Service)
@@ -123,7 +127,7 @@ func (sm *serviceMap) Register(rcvr RPCService) (string, error) {
 	}
 
 	sname = rcvr.Service()
-	if server := sm.GetService(sname); server == nil {
+	if server := sm.GetService(protocol, sname); server != nil {
 		return "", jerrors.New("service already defined: " + sname)
 	}
 	s.name = sname
@@ -138,7 +142,7 @@ func (sm *serviceMap) Register(rcvr RPCService) (string, error) {
 		log.Error(s)
 		return "", jerrors.New(s)
 	}
-	sm.serviceMap[s.name] = s
+	sm.serviceMap[protocol][s.name] = s
 
 	return strings.TrimSuffix(methods, ","), nil
 }
diff --git a/go.mod b/go.mod
index 5d8c0aec0c6a7dc54d260299617757ecd4fe2a5b..aa565e80bf028b554e99665b97ad788d031e13b6 100644
--- a/go.mod
+++ b/go.mod
@@ -4,15 +4,10 @@ require (
 	github.com/AlexStocks/getty v0.0.0-20190331201845-1ca64ac5a589
 	github.com/AlexStocks/goext v0.3.2
 	github.com/AlexStocks/log4go v1.0.2
-	github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
-	github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
 	github.com/dubbogo/hessian2 v0.0.0-20190410112310-f093e4436e31
 	github.com/juju/errors v0.0.0-20190207033735-e65537c515d7
-	github.com/juju/utils v0.0.0-20180820210520-bf9cc5bdd62d
-	github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 // indirect
-	github.com/prometheus/common v0.0.0-20181126121408-4724e9255275
 	github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
-	github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 // indirect
-	gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
+	github.com/stretchr/testify v1.3.0
+	github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5
 	gopkg.in/yaml.v2 v2.2.2
 )
diff --git a/go.sum b/go.sum
index b12dffcd781dba0544e4db8432d50c5c3c32f588..583504cf12d04edec2c711fe2dc7bea146123827 100644
--- a/go.sum
+++ b/go.sum
@@ -8,10 +8,6 @@ github.com/AlexStocks/goext v0.3.2/go.mod h1:3M5j9Pjge4CdkNg2WIjRLUeoPedJHHKwkkg
 github.com/AlexStocks/log4go v1.0.2 h1:1K5WM8KjSUECaoXUl8FSF05KGeCJDfBrhKUBsxwUvhk=
 github.com/AlexStocks/log4go v1.0.2/go.mod h1:6kCCRo/orDo8mh5CEDOeuSSM674wBQ8M6E0K8dVOIz4=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
@@ -86,8 +82,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd h1:22rhYEzttbrnKjgYh5pifnDluXHHcJ3uSOi2l8Nw+9A=
 github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd/go.mod h1:JrOIxq3vDxvtuEI7Kmm2yqkuBfuT9DMLFMnCyYHLaKM=
 github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd/go.mod h1:JrOIxq3vDxvtuEI7Kmm2yqkuBfuT9DMLFMnCyYHLaKM=
@@ -159,8 +153,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go
index c1c63f807d11a4e918b02e5c9f101920b23f5a70..2f1eed2ea41ffe9ba2a628c2893ce0c2f4fd399b 100644
--- a/protocol/dubbo/client.go
+++ b/protocol/dubbo/client.go
@@ -1,9 +1,7 @@
 package dubbo
 
 import (
-	"gopkg.in/yaml.v2"
 	"io/ioutil"
-	"math/rand"
 	"os"
 	"strings"
 	"sync"
@@ -16,6 +14,7 @@ import (
 	log "github.com/AlexStocks/log4go"
 	"github.com/dubbogo/hessian2"
 	jerrors "github.com/juju/errors"
+	"gopkg.in/yaml.v2"
 )
 
 import (
@@ -29,34 +28,40 @@ var (
 	errClientClosed      = jerrors.New("client closed")
 	errClientReadTimeout = jerrors.New("client read timeout")
 
-	conf *ClientConfig
+	clientConf *ClientConfig
 )
 
 const CONF_CLIENT_FILE_PATH = "CONF_CLIENT_FILE_PATH"
 
 func init() {
-	rand.Seed(time.Now().UnixNano())
 
-	conf = &ClientConfig{}
 	// load clientconfig from *.yml
 	path := os.Getenv(CONF_CLIENT_FILE_PATH)
 	if path == "" {
 		log.Info("CONF_CLIENT_FILE_PATH is null")
+		return
 	}
 
 	file, err := ioutil.ReadFile(path)
 	if err != nil {
 		log.Error(jerrors.Trace(err))
+		return
 	}
 
+	conf := &ClientConfig{}
 	err = yaml.Unmarshal(file, conf)
 	if err != nil {
 		log.Error(jerrors.Trace(err))
+		return
 	}
 
 	if err := conf.CheckValidity(); err != nil {
 		log.Error("ClientConfig check failed: ", jerrors.Trace(err))
+		return
 	}
+
+	clientConf = conf
+
 }
 
 type CallOptions struct {
@@ -127,9 +132,9 @@ func NewClient() *Client {
 
 	c := &Client{
 		pendingResponses: make(map[SequenceType]*PendingResponse),
-		conf:             *conf,
+		conf:             *clientConf,
 	}
-	c.pool = newGettyRPCClientConnPool(c, conf.PoolSize, time.Duration(int(time.Second)*conf.PoolTTL))
+	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
 
 	return c
 }
diff --git a/protocol/dubbo/dubbo_exporter.go b/protocol/dubbo/dubbo_exporter.go
index 274fdd3016bc56943f2f1aec31d82cbb1687aa5d..111b1782f0cd51305c60e7ed0dfc84c53a915b6d 100644
--- a/protocol/dubbo/dubbo_exporter.go
+++ b/protocol/dubbo/dubbo_exporter.go
@@ -1,5 +1,9 @@
 package dubbo
 
+import (
+	"sync"
+)
+
 import (
 	"github.com/dubbo/dubbo-go/protocol"
 )
@@ -8,7 +12,7 @@ type DubboExporter struct {
 	protocol.BaseExporter
 }
 
-func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap map[string]protocol.Exporter) *DubboExporter {
+func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *DubboExporter {
 	return &DubboExporter{
 		BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap),
 	}
diff --git a/protocol/dubbo/dubbo_invoker.go b/protocol/dubbo/dubbo_invoker.go
index 9d737877cf060a2501eb0f59481b662531fef2d4..c5882675b694c36b513c0357f72b91de91e9feef 100644
--- a/protocol/dubbo/dubbo_invoker.go
+++ b/protocol/dubbo/dubbo_invoker.go
@@ -26,7 +26,7 @@ type DubboInvoker struct {
 
 func NewDubboInvoker(url config.IURL, client *Client) *DubboInvoker {
 	return &DubboInvoker{
-		BaseInvoker: protocol.NewBaseInvoker(url),
+		BaseInvoker: *protocol.NewBaseInvoker(url),
 		client:      client,
 	}
 }
diff --git a/protocol/dubbo/dubbo_protocol.go b/protocol/dubbo/dubbo_protocol.go
index 271d3727db130d9fca0256c8c7bf83c5510974fd..eb6807b6978744a3076577dee818d2bb4ff5087d 100644
--- a/protocol/dubbo/dubbo_protocol.go
+++ b/protocol/dubbo/dubbo_protocol.go
@@ -62,7 +62,11 @@ func (dp *DubboProtocol) Destroy() {
 }
 
 func (dp *DubboProtocol) openServer(url config.URL) {
-	srv := NewServer(dp.ExporterMap()[url.Key()])
+	exporter, ok := dp.ExporterMap().Load(url.Key())
+	if !ok {
+		panic("[DubboProtocol]" + url.Key() + "is not existing")
+	}
+	srv := NewServer(exporter.(protocol.Exporter))
 	dp.serverMap[url.Location] = srv
 	srv.Start(url)
 }
diff --git a/protocol/dubbo/dubbo_protocol_test.go b/protocol/dubbo/dubbo_protocol_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9a7649ee491f63dca8805e54b7137d0563395498
--- /dev/null
+++ b/protocol/dubbo/dubbo_protocol_test.go
@@ -0,0 +1,70 @@
+package dubbo
+
+import (
+	"context"
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/dubbo/dubbo-go/config"
+	"github.com/dubbo/dubbo-go/protocol"
+)
+
+func TestDubboProtocol_Export(t *testing.T) {
+	// Export
+	proto := GetProtocol()
+	url, err := config.NewURL(context.Background(), "dubbo://192.168.56.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)
+	srvConf = &ServerConfig{}
+	exporter := proto.Export(protocol.NewBaseInvoker(url))
+
+	// make sure url
+	eq := exporter.GetInvoker().GetUrl().URLEqual(url)
+	assert.True(t, eq)
+
+	// make sure exporterMap after 'Unexport'
+	_, ok := proto.(*DubboProtocol).ExporterMap().Load(url.Key())
+	assert.True(t, ok)
+	exporter.Unexport()
+	_, ok = proto.(*DubboProtocol).ExporterMap().Load(url.Key())
+	assert.False(t, ok)
+
+	// make sure serverMap after 'Destroy'
+	_, ok = proto.(*DubboProtocol).serverMap[url.Location]
+	assert.True(t, ok)
+	proto.Destroy()
+	_, ok = proto.(*DubboProtocol).serverMap[url.Location]
+	assert.False(t, ok)
+}
+
+func TestDubboProtocol_Refer(t *testing.T) {
+	// Refer
+	proto := GetProtocol()
+	url, err := config.NewURL(context.Background(), "dubbo://192.168.56.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)
+	clientConf = &ClientConfig{}
+	invoker := proto.Refer(url)
+
+	// make sure url
+	eq := invoker.GetUrl().URLEqual(url)
+	assert.True(t, eq)
+
+	// make sure invokers after 'Destroy'
+	invokersLen := len(proto.(*DubboProtocol).Invokers())
+	assert.Equal(t, 1, invokersLen)
+	proto.Destroy()
+	invokersLen = len(proto.(*DubboProtocol).Invokers())
+	assert.Equal(t, 0, invokersLen)
+}
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
index 38a12e275f7011882b93a23001097c3524ea235b..5835b3295e663348cab6dc318c2a92648b2afb6e 100644
--- a/protocol/dubbo/listener.go
+++ b/protocol/dubbo/listener.go
@@ -261,6 +261,12 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) {
 	}
 	svc := svcIf.(*config.Service)
 	method := svc.Method()[req.Service.Method]
+	if method == nil {
+		log.Error("method not found!")
+		req.Header.ResponseStatus = hessian.Response_SERVICE_NOT_FOUND
+		req.Body = nil
+		return
+	}
 
 	// prepare argv
 	var argv reflect.Value
@@ -280,7 +286,7 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) {
 	// prepare replyv
 	replyv := reflect.New(method.ReplyType().Elem())
 	var returnValues []reflect.Value
-	if method.CtxType == nil {
+	if method.CtxType() == nil {
 		returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
 	} else {
 		if contextv := reflect.ValueOf(ctx); contextv.IsValid() {
diff --git a/protocol/dubbo/readwriter.go b/protocol/dubbo/readwriter.go
index be720e0090266674093bc127d4a59ea09cbd177e..2c870da834187b8dcc2a18adc797d96164d1a533 100644
--- a/protocol/dubbo/readwriter.go
+++ b/protocol/dubbo/readwriter.go
@@ -107,7 +107,7 @@ func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface
 			"dubboVersion": dubboVersion,
 			"argsTypes":    argsTypes,
 			"args":         args,
-			"service":      config.ServiceMap.GetService(pkg.Service.Target),
+			"service":      config.ServiceMap.GetService(DUBBO, pkg.Service.Target),
 			"attachments":  attachments,
 		}
 	}
diff --git a/protocol/invoker.go b/protocol/invoker.go
index 92236286495b6e75a198a3c58f3c51a9cd93cf35..03a39efa26c90e99d0cccf14aed8cb6de901bbfa 100644
--- a/protocol/invoker.go
+++ b/protocol/invoker.go
@@ -25,8 +25,8 @@ type BaseInvoker struct {
 	destroyed bool
 }
 
-func NewBaseInvoker(url config.IURL) BaseInvoker {
-	return BaseInvoker{
+func NewBaseInvoker(url config.IURL) *BaseInvoker {
+	return &BaseInvoker{
 		url:       url,
 		available: true,
 		destroyed: false,
diff --git a/protocol/jsonrpc/jsonrpc_exporter.go b/protocol/jsonrpc/jsonrpc_exporter.go
index dd0918281127ea647cd58e09d52751d83d2fe02c..3c6c16cbb6fe97830a86525b926d0c2f24da2453 100644
--- a/protocol/jsonrpc/jsonrpc_exporter.go
+++ b/protocol/jsonrpc/jsonrpc_exporter.go
@@ -1,5 +1,9 @@
 package jsonrpc
 
+import (
+	"sync"
+)
+
 import (
 	"github.com/dubbo/dubbo-go/protocol"
 )
@@ -8,7 +12,7 @@ type JsonrpcExporter struct {
 	protocol.BaseExporter
 }
 
-func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap map[string]protocol.Exporter) *JsonrpcExporter {
+func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *JsonrpcExporter {
 	return &JsonrpcExporter{
 		BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap),
 	}
diff --git a/protocol/jsonrpc/jsonrpc_invoker.go b/protocol/jsonrpc/jsonrpc_invoker.go
index 38b929c02fae7991e2bdc7fd77060089bc0a0c89..36952d3e38c166f10c02cb7e83756e6787b86db5 100644
--- a/protocol/jsonrpc/jsonrpc_invoker.go
+++ b/protocol/jsonrpc/jsonrpc_invoker.go
@@ -22,7 +22,7 @@ type JsonrpcInvoker struct {
 
 func NewJsonrpcInvoker(url config.IURL, client *HTTPClient) *JsonrpcInvoker {
 	return &JsonrpcInvoker{
-		BaseInvoker: protocol.NewBaseInvoker(url),
+		BaseInvoker: *protocol.NewBaseInvoker(url),
 		client:      client,
 	}
 }
diff --git a/protocol/jsonrpc/jsonrpc_protocol.go b/protocol/jsonrpc/jsonrpc_protocol.go
index cb6cd5258ce4eb5c5af26d1d4681b3d142577dc1..343e03ef389ab82e3292c808913a049d9d166584 100644
--- a/protocol/jsonrpc/jsonrpc_protocol.go
+++ b/protocol/jsonrpc/jsonrpc_protocol.go
@@ -67,7 +67,11 @@ func (jp *JsonrpcProtocol) Destroy() {
 }
 
 func (jp *JsonrpcProtocol) openServer(url config.URL) {
-	srv := NewServer(jp.ExporterMap()[url.Key()])
+	exporter, ok := jp.ExporterMap().Load(url.Key())
+	if !ok {
+		panic("[JsonrpcProtocol]" + url.Key() + "is not existing")
+	}
+	srv := NewServer(exporter.(protocol.Exporter))
 	jp.serverMap[url.Location] = srv
 	srv.Start(url)
 }
diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go
index 01950d3ab69d51ce755823b15ae80476957c17a5..465617b9246867b655cf33e39e84755a74e00a2a 100644
--- a/protocol/jsonrpc/server.go
+++ b/protocol/jsonrpc/server.go
@@ -272,7 +272,7 @@ func serveRequest(ctx context.Context,
 	}
 
 	// get method
-	svc := config.ServiceMap.GetService(serviceName)
+	svc := config.ServiceMap.GetService(JSONRPC, serviceName)
 	if svc == nil {
 		codec.ReadBody(nil)
 		return jerrors.New("cannot find svc " + serviceName)
diff --git a/protocol/protocol.go b/protocol/protocol.go
index a490ba4cb8f9fd76cffe5fb316f57621d737876d..6016115155ddc29ccec2e53d468f204cfc8b6a33 100644
--- a/protocol/protocol.go
+++ b/protocol/protocol.go
@@ -1,8 +1,15 @@
 package protocol
 
+import (
+	"sync"
+)
+
+import (
+	log "github.com/AlexStocks/log4go"
+)
+
 import (
 	"github.com/dubbo/dubbo-go/config"
-	"github.com/prometheus/common/log"
 )
 
 // Extension - Protocol
@@ -23,21 +30,21 @@ type Exporter interface {
 /////////////////////////////
 
 type BaseProtocol struct {
-	exporterMap map[string]Exporter
+	exporterMap *sync.Map
 	invokers    []Invoker
 }
 
 func NewBaseProtocol() BaseProtocol {
 	return BaseProtocol{
-		exporterMap: make(map[string]Exporter),
+		exporterMap: new(sync.Map),
 	}
 }
 
 func (bp *BaseProtocol) SetExporterMap(key string, exporter Exporter) {
-	bp.exporterMap[key] = exporter
+	bp.exporterMap.Store(key, exporter)
 }
 
-func (bp *BaseProtocol) ExporterMap() map[string]Exporter {
+func (bp *BaseProtocol) ExporterMap() *sync.Map {
 	return bp.exporterMap
 }
 
@@ -57,6 +64,7 @@ func (bp *BaseProtocol) Refer(url config.IURL) Invoker {
 	return nil
 }
 
+//Destroy will destroy all invoker and exporter, so it only is called once.
 func (bp *BaseProtocol) Destroy() {
 	// destroy invokers
 	for _, invoker := range bp.invokers {
@@ -67,13 +75,14 @@ func (bp *BaseProtocol) Destroy() {
 	bp.invokers = []Invoker{}
 
 	// unexport exporters
-	for key, exporter := range bp.ExporterMap() {
+	bp.exporterMap.Range(func(key, exporter interface{}) bool {
 		if exporter != nil {
-			exporter.Unexport()
+			exporter.(Exporter).Unexport()
 		} else {
-			delete(bp.exporterMap, key)
+			bp.exporterMap.Delete(key)
 		}
-	}
+		return true
+	})
 }
 
 /////////////////////////////
@@ -83,10 +92,10 @@ func (bp *BaseProtocol) Destroy() {
 type BaseExporter struct {
 	key         string
 	invoker     Invoker
-	exporterMap map[string]Exporter
+	exporterMap *sync.Map
 }
 
-func NewBaseExporter(key string, invoker Invoker, exporterMap map[string]Exporter) *BaseExporter {
+func NewBaseExporter(key string, invoker Invoker, exporterMap *sync.Map) *BaseExporter {
 	return &BaseExporter{
 		key:         key,
 		invoker:     invoker,
@@ -102,5 +111,5 @@ func (de *BaseExporter) GetInvoker() Invoker {
 func (de *BaseExporter) Unexport() {
 	log.Info("Exporter unexport.")
 	de.invoker.Destroy()
-	delete(de.exporterMap, de.key)
+	de.exporterMap.Delete(de.key)
 }