diff --git a/.gitignore b/.gitignore index 0b3673bf316a409b5caadf09f3fa58d42ad8f968..3d70f85a59b1367114bf04a7286fbb020d6825a4 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 diff --git a/README.md b/README.md index 97bf03da978637d1c1198a5d6b615a8eede3f7eb..b64ce4973d6df5efcb560058b857d455e6371a57 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,23 @@ Todo List: You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap). +## Document +Move [here](https://dubbogo.github.io/dubbo-go-website/) ## 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..0553527534506f21eb9bd154c034b8345298f93c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -54,10 +54,23 @@ Apache License, Version 2.0 浣犲彲浠ラ€氳繃璁块棶 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 鐭ラ亾鏇村鍏充簬 dubbo-go 鐨勪俊鎭� +## 鏂囨。 + +绉绘[杩欓噷](https://dubbogo.github.io/dubbo-go-website/) + ## 蹇€熷紑濮� ## 杩欎釜瀛愮洰褰曚笅鐨勪緥瀛愬睍绀轰簡濡備綍浣跨敤 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) 璐$尞浠g爜鎴栬€呮枃妗o紝鎴戜滑閮界儹鐑堟杩庛€傚叿浣撹鍙傝€� [contribution intro](https://github.com/apache/dubbo-go/blob/master/cg.md)銆� 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/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/common/constant/key.go b/common/constant/key.go index 82df44c3e10b6f19d2fba2c86fb7b5086904ab41..bca658b2623e3ca9241103b5f9c82c7e15fb4062 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -29,6 +29,7 @@ const ( SERVICE_KEY = "service" METHODS_KEY = "methods" TIMEOUT_KEY = "timeout" + BEAN_NAME_KEY = "bean.name" ) const ( @@ -44,7 +45,6 @@ const ( WEIGHT_KEY = "weight" WARMUP_KEY = "warmup" RETRIES_KEY = "retries" - BEAN_NAME = "bean.name" ) const ( 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 47b44cf57feb9cc9eadb18e597a935073918fe99..c594df235134d71d98b83c11b2f6eb9312283aae 100644 --- a/common/url.go +++ b/common/url.go @@ -136,6 +136,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 { diff --git a/config/base_config.go b/config/base_config.go index 19acea2fd6c738734734467daed7fb838bccdffd..54ad8aba368c7d9477faad6fbd97c5dccd32dca1 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -107,7 +107,8 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC setBaseValue := func(f reflect.Value) { ok, value := config.GetProperty(getKeyPrefix(val, id) + key) if ok { - if f.Kind() == reflect.Int64 { + switch f.Kind() { + case reflect.Int64: x, err := strconv.Atoi(value) if err != nil { logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", @@ -120,21 +121,16 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the int64 value {%v} from config center is overflow", int64(x))) } } - - } - - if f.Kind() == reflect.String { + case reflect.String: f.SetString(value) - } - if f.Kind() == reflect.Bool { + case reflect.Bool: x, err := strconv.ParseBool(value) if err != nil { logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", val.Type().Name(), val.Type().Field(i).Name, err) } f.SetBool(x) - } - if f.Kind() == reflect.Float64 { + case reflect.Float64: x, err := strconv.ParseFloat(value, 64) if err != nil { logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", @@ -147,7 +143,10 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the float64 value {%v} from config center is overflow", x)) } } + default: + logger.Warnf("The kind of field {%v} is not supported ", f.Kind().String()) } + } } @@ -180,25 +179,32 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } if f.Kind() == reflect.Map { - //initiate config - s := reflect.New(f.Type().Elem().Elem()) - prefix := s.MethodByName("Prefix").Call(nil)[0].String() - m := config.GetSubProperty(prefix) - for k := range m { - f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem())) + if f.Type().Elem().Kind() == reflect.Ptr { + //initiate config + s := reflect.New(f.Type().Elem().Elem()) + prefix := s.MethodByName("Prefix").Call(nil)[0].String() + m := config.GetSubProperty(prefix) + for k := range m { + f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem())) + } } + //iter := f.MapRange() for _, k := range f.MapKeys() { v := f.MapIndex(k) - if v.Kind() == reflect.Ptr { + switch v.Kind() { + case reflect.Ptr: if v.Elem().Kind() == reflect.Struct { setFieldValue(v.Elem(), k, config) } else { setBaseValue(v.Elem()) } + case reflect.Int64, reflect.String, reflect.Bool, reflect.Float64: + setBaseValue(v) + default: + logger.Warnf("The kind of field {%v} is not supported ", v.Kind().String()) } - } } 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..0dd0fb7f963e09a4402f4fd01c8a6b91959a7ca3 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -46,11 +46,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 +58,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 +65,16 @@ 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 { + 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 @@ -121,18 +114,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 +136,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 6e9689c76322686fff0fab585dc08436a07cd55c..107fea0b1d737f7be92d3e0042b6eebb7add78ed 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -45,15 +45,16 @@ 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) assert.NotEqual(t, ConsumerConfig{}, GetConsumerConfig()) assert.NotNil(t, providerConfig) assert.NotEqual(t, ProviderConfig{}, GetProviderConfig()) + assert.Equal(t, "soa.com.ikurento.user.UserProvider", GetConsumerConfig().References["UserProvider"].Params["serviceid"]) } func TestLoad(t *testing.T) { @@ -70,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{} @@ -83,6 +84,7 @@ func TestLoad(t *testing.T) { consumerConfig = nil providerConfig = nil } + func TestWithNoRegLoad(t *testing.T) { doInit() doinit() @@ -98,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{} @@ -111,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{} @@ -126,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 32c3ce167cf5685203170e347e17aad7eed044f9..55082ffe41ad0a38ccbb6c2e788f0b609a8b4ef8 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -62,6 +62,7 @@ func (*ConsumerConfig) Prefix() string { func SetConsumerConfig(c ConsumerConfig) { consumerConfig = &c } + func GetConsumerConfig() ConsumerConfig { if consumerConfig == nil { logger.Warnf("consumerConfig is nil!") @@ -70,7 +71,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/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 aa9b551dfa8abd299b813d8cb5b3af598e86fd5a..db8abaf73e9609b3f3ac1db68e89a3d66068659b 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -64,7 +64,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 2c38d8aa4aa31576c94724d4537aa752df2fb96c..a5b7d50db51df02cd1871b3fb6d0bd2d6a545dd2 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -38,19 +38,21 @@ import ( type ReferenceConfig struct { context context.Context pxy *proxy.Proxy - 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"` - Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"` - Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` - Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` - Group string `yaml:"group" json:"group,omitempty" property:"group"` - Version string `yaml:"version" json:"version,omitempty" property:"version"` - Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` - async bool `yaml:"async" json:"async,omitempty" property:"async"` + 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"` + Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` + Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` + Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"` + Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"` + Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` + Group string `yaml:"group" json:"group,omitempty" property:"group"` + Version string `yaml:"version" json:"version,omitempty" property:"version"` + Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` + async bool `yaml:"async" json:"async,omitempty" property:"async"` + Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` invoker protocol.Invoker urls []*common.URL } @@ -59,8 +61,9 @@ 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 { @@ -75,7 +78,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 != "" { @@ -143,6 +146,10 @@ func (refconfig *ReferenceConfig) GetRPCService() common.RPCService { func (refconfig *ReferenceConfig) getUrlMap() url.Values { urlMap := url.Values{} + //first set user params + for k, v := range refconfig.Params { + urlMap.Set(k, v) + } urlMap.Set(constant.INTERFACE_KEY, refconfig.InterfaceName) urlMap.Set(constant.TIMESTAMP_KEY, strconv.FormatInt(time.Now().Unix(), 10)) urlMap.Set(constant.CLUSTER_KEY, refconfig.Cluster) diff --git a/config/reference_config_test.go b/config/reference_config_test.go index c41e2a16de1cdc347d204cfae9d36b0b54f12808..296cde65fad6017b930ef06e0045a45b4af27c86 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -80,8 +80,11 @@ func doInit() { }, References: map[string]*ReferenceConfig{ "MockService": { + Params: map[string]string{ + "serviceid": "soa.mock", + }, Registry: "shanghai_reg1,shanghai_reg2,hangzhou_reg1,hangzhou_reg2", - InterfaceName: "MockService", + InterfaceName: "com.MockService", Protocol: "mock", Cluster: "failover", Loadbalance: "random", @@ -125,6 +128,7 @@ func Test_Refer(t *testing.T) { for _, reference := range consumerConfig.References { reference.Refer() + assert.Equal(t, "soa.mock", reference.Params["serviceid"]) assert.NotNil(t, reference.invoker) assert.NotNil(t, reference.pxy) } @@ -143,6 +147,7 @@ func Test_ReferP2P(t *testing.T) { } consumerConfig = nil } + func Test_ReferMultiP2P(t *testing.T) { doInit() extension.SetProtocol("dubbo", GetProtocol) diff --git a/config/registry_config.go b/config/registry_config.go index 1a926b459e598ff313e141a39956dc88cb3daad3..3d54c348aadd2a2f836849d12e50887c36909d31 100644 --- a/config/registry_config.go +++ b/config/registry_config.go @@ -68,13 +68,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) 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 79a29aa33058dfc47fca282a71ba28292a2b1ff3..76913319f6f0ac27ec36ebaa2d89db09bbd79c7c 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -43,17 +43,19 @@ import ( type ServiceConfig struct { context context.Context - 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"` - Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"` - Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"` - Loadbalance string `default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` - Group string `yaml:"group" json:"group,omitempty" property:"group"` - Version string `yaml:"version" json:"version,omitempty" property:"version" ` - Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` - Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"` - Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` + 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"` + Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"` + Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"` + Loadbalance string `default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + Group string `yaml:"group" json:"group,omitempty" property:"group"` + Version string `yaml:"version" json:"version,omitempty" property:"version" ` + Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` + Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"` + Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` + Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` unexported *atomic.Bool exported *atomic.Bool rpcService common.RPCService @@ -66,8 +68,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 +105,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 { @@ -148,6 +151,10 @@ func (srvconfig *ServiceConfig) Implement(s common.RPCService) { func (srvconfig *ServiceConfig) getUrlMap() url.Values { urlMap := url.Values{} + //first set user params + for k, v := range srvconfig.Params { + urlMap.Set(k, v) + } urlMap.Set(constant.INTERFACE_KEY, srvconfig.InterfaceName) urlMap.Set(constant.TIMESTAMP_KEY, strconv.FormatInt(time.Now().Unix(), 10)) urlMap.Set(constant.CLUSTER_KEY, srvconfig.Cluster) 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 08ff59f6fc403a0aa31e090fa8f9341a6e11d490..85e0eb2fe980b461c3eea1741d53c3b5064b8d47 100644 --- a/config/testdata/consumer_config.yml +++ b/config/testdata/consumer_config.yml @@ -36,12 +36,17 @@ 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" retries: 3 + params: + "serviceid": + "soa.com.ikurento.user.UserProvider" protocol_conf: dubbo: @@ -49,7 +54,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/config/testdata/consumer_config_with_configcenter.yml b/config/testdata/consumer_config_with_configcenter.yml index df896d2442ce6eb5cf0cc41bb92f39964325d885..1a33ec3971c231012265d0ce078aedf2f851a215 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: diff --git a/config/testdata/provider_config.yml b/config/testdata/provider_config.yml index 38952220e270b2b0a929a7583d1f5650ecab0121..3b6e43a51adabfa5ed2abbc3ef0f261ade576127 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,7 +55,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/dubbo/go-client/app/client.go b/examples/dubbo/go-client/app/client.go index 7918e2df0fbb2c488569791beefa6d872ca22564..0b77e60ceca921f2327a98abbe9540938296a85b 100644 --- a/examples/dubbo/go-client/app/client.go +++ b/examples/dubbo/go-client/app/client.go @@ -59,6 +59,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) + }) + + // 瑕佷箞fastFailTimeout鏃堕棿鍐呮墽琛屽畬姣曚笅闈㈢殑閫昏緫鐒跺悗绋嬪簭閫€鍑猴紝瑕佷箞鎵ц涓婇潰鐨勮秴鏃跺嚱鏁扮▼搴忓己琛岄€€鍑� + 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 +148,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/dubbo/go-client/app/user.go index d491c3633384ad9ee6acdb2786d383e420f26db3..ac64d0681140883d7d34f610fda76f08f200911c 100644 --- a/examples/dubbo/go-client/app/user.go +++ b/examples/dubbo/go-client/app/user.go @@ -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 ( @@ -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/dubbo/go-client/profiles/dev/client.yml b/examples/dubbo/go-client/profiles/dev/client.yml index 1595f23c34d3a374c47678ecc7350696e1d8b2c9..e1131df77e0709b78e897c8a2686c60f2b3bd8e5 100644 --- a/examples/dubbo/go-client/profiles/dev/client.yml +++ b/examples/dubbo/go-client/profiles/dev/client.yml @@ -18,7 +18,6 @@ application_config: registries : "hangzhouzk": - # 瀵瑰簲java閰嶇疆涓璦ddress灞炴€х殑zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/> protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" @@ -39,8 +38,27 @@ references: interface : "com.ikurento.user.UserProvider" cluster: "failover" methods : - - name: "GetUser" - retries: 3 + - 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: diff --git a/examples/dubbo/go-client/profiles/release/client.yml b/examples/dubbo/go-client/profiles/release/client.yml index 7a193ea64d783220f016c6b6220d602a5c586129..dabde06c753174e41a3655833877169a124f4ee3 100644 --- a/examples/dubbo/go-client/profiles/release/client.yml +++ b/examples/dubbo/go-client/profiles/release/client.yml @@ -35,13 +35,30 @@ references: # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� registry: "hangzhouzk" protocol : "dubbo" -# version: "2.0" -# group: "as" 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: @@ -49,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: diff --git a/examples/dubbo/go-client/profiles/test/client.yml b/examples/dubbo/go-client/profiles/test/client.yml index 24ede19d7d2365fb9c7d92d31bc312cfc7935388..e0b742eff4c4652114bc43cbf315365cac41d242 100644 --- a/examples/dubbo/go-client/profiles/test/client.yml +++ b/examples/dubbo/go-client/profiles/test/client.yml @@ -35,13 +35,30 @@ references: # 鍙互鎸囧畾澶氫釜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 + "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: @@ -49,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: diff --git a/examples/dubbo/go-server/app/server.go b/examples/dubbo/go-server/app/server.go index 788fc665b872d4f7f1429122cee581a6ab4979e7..23c9b7e659b5a2d08094a74dbe4c0980d491eed2 100644 --- a/examples/dubbo/go-server/app/server.go +++ b/examples/dubbo/go-server/app/server.go @@ -74,7 +74,7 @@ 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) }) diff --git a/examples/dubbo/go-server/app/user.go b/examples/dubbo/go-server/app/user.go index 3c261dc029022fe8a3a80a4007e5aa132643eb7c..dee0dd5eaec989fde13ab878d3d6bb1221d93901 100644 --- a/examples/dubbo/go-server/app/user.go +++ b/examples/dubbo/go-server/app/user.go @@ -18,7 +18,6 @@ package main import ( - "context" "fmt" "strconv" "time" @@ -26,20 +25,10 @@ import ( 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 @@ -86,10 +75,6 @@ type ( Time time.Time Sex Gender // 娉ㄦ剰姝ゅ锛宩ava enum Object <--> go string } - - UserProvider struct { - user map[string]User - } ) var ( @@ -98,17 +83,17 @@ var ( Sex: Gender(MAN), } - userMap = UserProvider{user: make(map[string]User)} + userMap = 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 { + 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.user[k] = v + userMap[k] = v } } @@ -123,92 +108,6 @@ 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/go-server/app/user_provider.go b/examples/dubbo/go-server/app/user_provider.go new file mode 100644 index 0000000000000000000000000000000000000000..7b3721d0c7498a88a9beaa9ee0a1db830e634417 --- /dev/null +++ b/examples/dubbo/go-server/app/user_provider.go @@ -0,0 +1,102 @@ +package main + +import ( + "context" + "fmt" + "strconv" +) + +import ( + "github.com/apache/dubbo-go/config" + "github.com/dubbogo/hessian2/java_exception" + 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/dubbo/go-server/app/user_provider1.go b/examples/dubbo/go-server/app/user_provider1.go new file mode 100644 index 0000000000000000000000000000000000000000..d1019730363bd6bea45dcca4141fdd54dedfb800 --- /dev/null +++ b/examples/dubbo/go-server/app/user_provider1.go @@ -0,0 +1,88 @@ +package main + +import ( + "context" + "fmt" + "strconv" +) + +import ( + "github.com/apache/dubbo-go/config" + "github.com/dubbogo/hessian2/java_exception" + 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/dubbo/go-server/app/user_provider2.go b/examples/dubbo/go-server/app/user_provider2.go new file mode 100644 index 0000000000000000000000000000000000000000..556301ca5af84e293148c80cadf6d6711c4813b1 --- /dev/null +++ b/examples/dubbo/go-server/app/user_provider2.go @@ -0,0 +1,97 @@ +package main + +import ( + "context" + "fmt" + "strconv" +) + +import ( + "github.com/apache/dubbo-go/config" + "github.com/dubbogo/hessian2/java_exception" + 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/dubbo/go-server/profiles/dev/server.yml b/examples/dubbo/go-server/profiles/dev/server.yml index bc4b288542322c8644c7af643dcb8dfafa099b1a..2f0decaec6b1ad8bc46d1cea5f3c3d04dc8bc144 100644 --- a/examples/dubbo/go-server/profiles/dev/server.yml +++ b/examples/dubbo/go-server/profiles/dev/server.yml @@ -27,7 +27,6 @@ registries : services: - "UserProvider": # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� registry: "hangzhouzk" @@ -38,21 +37,45 @@ services: warmup: "100" cluster: "failover" methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + - 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 + 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/dubbo/go-server/profiles/release/server.yml b/examples/dubbo/go-server/profiles/release/server.yml index 3db12902f1d349e1703f2f977c682c61b0d35938..92306b706785c55e03c5a496b613b32ca361875c 100644 --- a/examples/dubbo/go-server/profiles/release/server.yml +++ b/examples/dubbo/go-server/profiles/release/server.yml @@ -39,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": @@ -50,7 +75,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/dubbo/go-server/profiles/test/server.yml b/examples/dubbo/go-server/profiles/test/server.yml index 12f10e004c6b1b5ea1afcf37fe79306bd4d10d82..03140d6bde21b79bd63719328cff0a5732ab47b3 100644 --- a/examples/dubbo/go-server/profiles/test/server.yml +++ b/examples/dubbo/go-server/profiles/test/server.yml @@ -36,21 +36,45 @@ services: warmup: "100" cluster: "failover" methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + - 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 + 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/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java index edf4c0d2b20a08c17241132cd03bf16a51b2fbb8..9122a629f49cb1e5eeee1641e89fa0c91091e960 100644 --- 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 @@ -19,23 +19,32 @@ import java.util.List; public class Consumer { //瀹氫箟涓€涓鏈夊彉閲� 锛圫pring涓姹傦級 private UserProvider userProvider; + private UserProvider userProvider1; + private UserProvider userProvider2; //Spring娉ㄥ叆锛圫pring涓姹傦級 public void setUserProvider(UserProvider u) { this.userProvider = u; } + public void setUserProvider1(UserProvider u) { + this.userProvider1 = u; + } + public void setUserProvider2(UserProvider u) { + this.userProvider2 = 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); - } + //鍚姩consumer鐨勫叆鍙e嚱鏁�(鍦ㄩ厤缃枃浠朵腑鎸囧畾) + 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 { @@ -49,12 +58,12 @@ public class Consumer { + ", 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()); + " 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()); + " 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"); @@ -86,16 +95,114 @@ public class Consumer { " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString() + ", age:" + user.getAge() + ", time:" + user.getTime().toString()); } - } catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - //鍚姩consumer鐨勫叆鍙e嚱鏁�(鍦ㄩ厤缃枃浠朵腑鎸囧畾) - public void start() throws Exception { - testGetUser(); - testGetUsers(); -// Thread.sleep(120000); -Thread.sleep(2000); + 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/resources/META-INF/spring/dubbo.consumer.xml b/examples/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/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/dubbo/java-client/src/main/resources/META-INF/spring/service.xml b/examples/dubbo/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/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/with-configcenter-go-client/app/user.go b/examples/dubbo/with-configcenter-go-client/app/user.go index d491c3633384ad9ee6acdb2786d383e420f26db3..bbc55283bf728e4f8287ed3647e05c856a81cf34 100644 --- a/examples/dubbo/with-configcenter-go-client/app/user.go +++ b/examples/dubbo/with-configcenter-go-client/app/user.go @@ -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/with-configcenter-go-client/profiles/dev/client.yml b/examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml index c809041f14d15230a02f154571c02a038ee2ca92..1ebdf5bb5c97c3f45d9a0b551afd78866868d4d0 100644 --- a/examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml +++ b/examples/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: diff --git a/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml b/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml index c809041f14d15230a02f154571c02a038ee2ca92..1ebdf5bb5c97c3f45d9a0b551afd78866868d4d0 100644 --- a/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml +++ b/examples/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: diff --git a/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml b/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml index c809041f14d15230a02f154571c02a038ee2ca92..1ebdf5bb5c97c3f45d9a0b551afd78866868d4d0 100644 --- a/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml +++ b/examples/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: diff --git a/examples/dubbo/with-configcenter-go-server/app/user.go b/examples/dubbo/with-configcenter-go-server/app/user.go index b84e7229cc62ce5b3c8e8b0a3927c55b2aff9df8..def7eec101eff6a6229c85c9832b336f4cc35a9f 100644 --- a/examples/dubbo/with-configcenter-go-server/app/user.go +++ b/examples/dubbo/with-configcenter-go-server/app/user.go @@ -25,13 +25,13 @@ import ( ) import ( + hessian "github.com/dubbogo/hessian2" + "github.com/dubbogo/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 @@ -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/with-configcenter-go-server/profiles/dev/server.yml b/examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml index 05f758592f5aa69e097f19d14299e15bc9bf5f0f..a2ae2fe5d89519056e07fbc11d7d34407d449fed 100644 --- a/examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml +++ b/examples/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 diff --git a/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml b/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml index 05f758592f5aa69e097f19d14299e15bc9bf5f0f..a2ae2fe5d89519056e07fbc11d7d34407d449fed 100644 --- a/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml +++ b/examples/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 diff --git a/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml b/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml index 05f758592f5aa69e097f19d14299e15bc9bf5f0f..a2ae2fe5d89519056e07fbc11d7d34407d449fed 100644 --- a/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml +++ b/examples/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 diff --git a/examples/jsonrpc/go-client/app/client.go b/examples/jsonrpc/go-client/app/client.go index 478a88d19404be612c1caf6be4885edc01bb414b..b781f860bc41cdc616f8836499d584056c29af43 100644 --- a/examples/jsonrpc/go-client/app/client.go +++ b/examples/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) + }) + + // 瑕佷箞fastFailTimeout鏃堕棿鍐呮墽琛屽畬姣曚笅闈㈢殑閫昏緫鐒跺悗绋嬪簭閫€鍑猴紝瑕佷箞鎵ц涓婇潰鐨勮秴鏃跺嚱鏁扮▼搴忓己琛岄€€鍑� + 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/jsonrpc/go-client/app/user.go index ca98b1af0b3c1379c73623162546db9fb4fc95d6..c6fdbe13a8533c1bfb5ac4d442ef0c3ec968c298 100644 --- a/examples/jsonrpc/go-client/app/user.go +++ b/examples/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/go-client/profiles/dev/client.yml b/examples/jsonrpc/go-client/profiles/dev/client.yml index 8d4346510fac9f7350b3d680b07a3d258b84e521..788e06eecd6014eefaf12913b6394e5e0a95efdf 100644 --- a/examples/jsonrpc/go-client/profiles/dev/client.yml +++ b/examples/jsonrpc/go-client/profiles/dev/client.yml @@ -8,12 +8,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 : "dev" registries : "hangzhouzk": @@ -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" + - 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/go-client/profiles/release/client.yml b/examples/jsonrpc/go-client/profiles/release/client.yml index 3b82dd07bd0b41ace267721d151238c71beaa5a4..0084e5b04d48fea480f22df8e031eb91e1d6e835 100644 --- a/examples/jsonrpc/go-client/profiles/release/client.yml +++ b/examples/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/go-client/profiles/test/client.yml b/examples/jsonrpc/go-client/profiles/test/client.yml index 1b0529c455a9492d68d040632451bd13198552a4..3efdedad4ab8acffb9d8724273deb8c12117837d 100644 --- a/examples/jsonrpc/go-client/profiles/test/client.yml +++ b/examples/jsonrpc/go-client/profiles/test/client.yml @@ -8,12 +8,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 : "test" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "test" registries : "hangzhouzk": @@ -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" + - 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/go-server/app/server.go b/examples/jsonrpc/go-server/app/server.go index 8a226e23ad74960612ef1cfe2f82740a6e7516d8..231082b5b4accbbb9aa78b2241416f0c8014c5ef 100644 --- a/examples/jsonrpc/go-server/app/server.go +++ b/examples/jsonrpc/go-server/app/server.go @@ -64,7 +64,7 @@ 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) }) diff --git a/examples/jsonrpc/go-server/app/user.go b/examples/jsonrpc/go-server/app/user.go index e86d915417cc54b05faa25ebaa06dae2c5fb6dd1..837661003e75f1d8c2d5442c756f45cb32f5d590 100644 --- a/examples/jsonrpc/go-server/app/user.go +++ b/examples/jsonrpc/go-server/app/user.go @@ -18,26 +18,12 @@ 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 @@ -61,10 +47,6 @@ type ( Birth int `json:"time"` Sex string `json:"sex"` } - - UserProvider struct { - user map[string]User - } ) var ( @@ -75,103 +57,20 @@ var ( sex: Gender(MAN), } - userMap = UserProvider{user: make(map[string]User)} + userMap = 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 { + 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.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) + v.Sex = userMap[k].sex.String() + userMap[k] = v } - 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{}) { diff --git a/examples/jsonrpc/go-server/app/user_provider.go b/examples/jsonrpc/go-server/app/user_provider.go new file mode 100644 index 0000000000000000000000000000000000000000..4af4bb040484eb8613c50545e93312aa232f7de2 --- /dev/null +++ b/examples/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/jsonrpc/go-server/app/user_provider1.go b/examples/jsonrpc/go-server/app/user_provider1.go new file mode 100644 index 0000000000000000000000000000000000000000..1557c6b8d22c3e6969e8b48b87008576eb71a984 --- /dev/null +++ b/examples/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/jsonrpc/go-server/app/user_provider2.go b/examples/jsonrpc/go-server/app/user_provider2.go new file mode 100644 index 0000000000000000000000000000000000000000..7d2fb80a99763235610628865b4704a3999c489b --- /dev/null +++ b/examples/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/go-server/profiles/dev/server.yml b/examples/jsonrpc/go-server/profiles/dev/server.yml index b5384a28a37535bf7493d6ae07166f6da3b4c440..4d74d2ef6fed9b0206729717d7b7081a3eadec96 100644 --- a/examples/jsonrpc/go-server/profiles/dev/server.yml +++ b/examples/jsonrpc/go-server/profiles/dev/server.yml @@ -2,12 +2,12 @@ # application config application_config: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "dev" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "dev" registries : "hangzhouzk": @@ -25,26 +25,51 @@ registries : services: - "UserProvider": - # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� - registry: "hangzhouzk" - protocol : "jsonrpc" - # 鐩稿綋浜巇ubbo.xml涓殑interface - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + "UserProvider": + # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� + registry: "hangzhouzk" + protocol : "jsonrpc" + # 鐩稿綋浜巇ubbo.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 + 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 index 213d31d53eb2523e2e132810c7435b3696581a31..3f7d2fdfff208801a6b89e7a90350e57133f31c3 100644 --- a/examples/jsonrpc/go-server/profiles/release/server.yml +++ b/examples/jsonrpc/go-server/profiles/release/server.yml @@ -25,19 +25,44 @@ registries : services: - "UserProvider": - # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� - registry: "hangzhouzk" - protocol : "jsonrpc" - # 鐩稿綋浜巇ubbo.xml涓殑interface - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + "UserProvider": + # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� + registry: "hangzhouzk" + protocol : "jsonrpc" + # 鐩稿綋浜巇ubbo.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" diff --git a/examples/jsonrpc/go-server/profiles/test/server.yml b/examples/jsonrpc/go-server/profiles/test/server.yml index 9b6dcb0b5c4513cf12ec5a505be64be156593c94..dd0637e7970281236b92e37888c554d83d87de96 100644 --- a/examples/jsonrpc/go-server/profiles/test/server.yml +++ b/examples/jsonrpc/go-server/profiles/test/server.yml @@ -2,12 +2,12 @@ # application config application_config: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "test" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "test" registries : "hangzhouzk": @@ -25,26 +25,51 @@ registries : services: - "UserProvider": - # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� - registry: "hangzhouzk" - protocol : "jsonrpc" - # 鐩稿綋浜巇ubbo.xml涓殑interface - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + "UserProvider": + # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� + registry: "hangzhouzk" + protocol : "jsonrpc" + # 鐩稿綋浜巇ubbo.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 + 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 index ddf899aa10979d65f9c88bc0b79ccbb065812417..2c7b27b5e6a494420a57d6614a8f76017fccbea7 100644 --- 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 @@ -19,23 +19,32 @@ import java.util.List; public class Consumer { //瀹氫箟涓€涓鏈夊彉閲� 锛圫pring涓姹傦級 private UserProvider userProvider; + private UserProvider userProvider1; + private UserProvider userProvider2; //Spring娉ㄥ叆锛圫pring涓姹傦級 public void setUserProvider(UserProvider u) { this.userProvider = u; } + public void setUserProvider1(UserProvider u) { + this.userProvider1 = u; + } + public void setUserProvider2(UserProvider u) { + this.userProvider2 = 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); - } + //鍚姩consumer鐨勫叆鍙e嚱鏁�(鍦ㄩ厤缃枃浠朵腑鎸囧畾) + 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 { @@ -53,12 +62,12 @@ public class Consumer { + ", 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()); + " 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()); + " 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"); @@ -82,16 +91,106 @@ public class Consumer { " UserInfo, Id:" + user.getId() + ", name:" + user.getName() + ", sex:" + user.getSex().toString() + ", age:" + user.getAge() + ", time:" + user.getTime().toString()); } - } catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - //鍚姩consumer鐨勫叆鍙e嚱鏁�(鍦ㄩ厤缃枃浠朵腑鎸囧畾) - public void start() throws Exception { - testGetUser(); - testGetUsers(); -// Thread.sleep(120000); -Thread.sleep(2000); + 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/resources/META-INF/spring/dubbo.consumer.xml b/examples/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/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/jsonrpc/java-client/src/main/resources/META-INF/spring/service.xml b/examples/jsonrpc/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/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/with-configcenter-go-client/app/user.go b/examples/jsonrpc/with-configcenter-go-client/app/user.go index ca98b1af0b3c1379c73623162546db9fb4fc95d6..fef665bb3d14709ffd584cbb184c18ffe8d87580 100644 --- a/examples/jsonrpc/with-configcenter-go-client/app/user.go +++ b/examples/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/jsonrpc/with-configcenter-go-server/app/user.go b/examples/jsonrpc/with-configcenter-go-server/app/user.go index fbe6f3339c212d2bd42d52b6bbf7c7fcec6fb9c3..9ab9e58cb4d469dda347519674a8eef85b429fce 100644 --- a/examples/jsonrpc/with-configcenter-go-server/app/user.go +++ b/examples/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/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/go.sum b/go.sum index ff8b97bcadfa94b71a9c2c720762f95df1dbefcd..2e5e91aeab63a232ab70c0c248bddf3849da86bf 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/dubbogo/getty v1.2.0/go.mod h1:p9Pyk18a+5Aa0GZ546aCzlehEfvEof0jAF0+QQ github.com/dubbogo/gost v1.0.1-0.20190706005735-65c3ecbba418/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg= github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI= github.com/dubbogo/gost v1.1.1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg= +github.com/dubbogo/gostd v0.0.0-20190625030817-87d8669125b7 h1:Wmt8yQMGkNx4GDUvU4CA+dwIsDwgi+DbP28NZV2ruqQ= +github.com/dubbogo/gostd v0.0.0-20190625030817-87d8669125b7/go.mod h1:lQ7PmKvs6xplvjzEEMKw8XmP20D9raD+wFfzxkKaBd4= github.com/dubbogo/hessian2 v1.2.0 h1:5wFYuMzzRhneUAPbVBVKubIknrEjUM/B76vievYD0Vw= github.com/dubbogo/hessian2 v1.2.0/go.mod h1:7EohF3mE7xmZcj43nP172sapRHOEifcV/jwyHhG4SaY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go index 8ba46e7b0b321095652fb7c6d0c1c7403e1fea1e..c60b265cbcc0fd9ff2b98b036bf9a55a5e4a6241 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -93,53 +93,15 @@ func GetClientConf() ClientConfig { return *clientConf } -type CallOptions struct { +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 +111,7 @@ type CallResponse struct { type AsyncCallback func(response CallResponse) type Client struct { + opts Options conf ClientConfig pool *gettyRPCClientPool sequence atomic.Uint64 @@ -156,9 +119,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 +140,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 { - - var copts CallOptions - for _, o := range opts { - o(&copts) - } + callback AsyncCallback, reply interface{}) error { - 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 +180,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 +190,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 +207,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 +233,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 +260,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..8c24098b482979f5680ad74eaef37656473c8267 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/dubbogo/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{ @@ -173,9 +184,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, @@ -195,11 +205,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×tamp=1556509797245") + "side=provider&timeout=3000×tamp=1556509797245&bean.name=UserProvider") assert.NoError(t, err) proto.Export(protocol.NewBaseInvoker(url)) @@ -274,12 +284,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..790397da35ced7cff76e4b4027ddba883ed9f250 100644 --- a/protocol/dubbo/codec.go +++ b/protocol/dubbo/codec.go @@ -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..f5b27ea1d7b7be01aeb425b144e8b8971d214c7d 100644 --- a/protocol/dubbo/codec_test.go +++ b/protocol/dubbo/codec_test.go @@ -20,10 +20,11 @@ package dubbo import ( "testing" "time" +) - "github.com/stretchr/testify/assert" - +import ( hessian "github.com/dubbogo/hessian2" + "github.com/stretchr/testify/assert" ) 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..e59b7f2fd85fb216adb86a8167980abed45be9e3 100644 --- a/protocol/dubbo/config.go +++ b/protocol/dubbo/config.go @@ -48,32 +48,17 @@ 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 - // session tcp parameters GettySessionParam GettySessionParam `required:"true" yaml:"getty_session_param" json:"getty_session_param,omitempty"` } // 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,10 +72,6 @@ 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"` @@ -125,6 +106,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 +116,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 +126,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..1333fd3dc6f5baef51b3aae5ea8255397008dd2c 100644 --- a/protocol/dubbo/listener.go +++ b/protocol/dubbo/listener.go @@ -208,12 +208,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 +223,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..23e860c19c1ec0540da54e99a4d6c84496c18849 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) } @@ -166,7 +168,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 +197,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 +245,11 @@ func (c *gettyRPCClient) close() error { type gettyRPCClientPool struct { rpcClient *Client - size int // []*gettyRPCClient鏁扮粍鐨剆ize - ttl int64 // 姣忎釜gettyRPCClient鐨勬湁鏁堟湡鏃堕棿. pool瀵硅薄浼氬湪getConn鏃舵墽琛宼tl妫€鏌� + size int // size of []*gettyRPCClient + ttl int64 // ttl of every gettyRPCClient, it is checked when getConn sync.Mutex - conns []*gettyRPCClient // 浠嶽]*gettyRPCClient 鍙key鏄繛鎺ュ湴鍧€锛岃€寁alue鏄搴旇繖涓湴鍧€鐨勮繛鎺ユ暟缁� + conns []*gettyRPCClient } func newGettyRPCClientConnPool(rpcClient *Client, size int, ttl time.Duration) *gettyRPCClientPool { @@ -270,7 +274,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 +290,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..1b4db88e556a7ef724697b3f497a687e4e39859e 100644 --- a/protocol/dubbo/readwriter.go +++ b/protocol/dubbo/readwriter.go @@ -24,7 +24,7 @@ import ( import ( "github.com/dubbogo/getty" - hessian "github.com/dubbogo/hessian2" + "github.com/dubbogo/hessian2" perrors "github.com/pkg/errors" ) import ( @@ -140,11 +140,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/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/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×tamp=1556509797245") + "side=provider&timeout=3000×tamp=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×tamp=1556509797245") + "side=provider&timeout=3000×tamp=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/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go index 22658e1adcd57d6b88bdbf3949cae08f90f1cfb5..2b5e2f8f7caf749be28bf3ff6e5d14980d70f2f4 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -36,13 +36,13 @@ import ( func Test_Register(t *testing.T) { regurl, _ := common.NewURL(context.TODO(), "registry://127.0.0.1:1111", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) - url, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"})) + url, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithParamsValue("serviceid", "soa.mock"), common.WithMethods([]string{"GetUser", "AddUser"})) ts, reg, _ := newMockZkRegistry(®url) defer ts.Stop() err := reg.Register(url) children, _ := reg.client.GetChildren("/dubbo/com.ikurento.user.UserProvider/providers") - 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.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.*.serviceid%3Dsoa.mock%26.*provider", children) assert.NoError(t, err) } diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index b94483835c8bcf913de9e40ec4a6ffba3334c103..0e3e502115dee3e1ee1f98f070774fe98b009ac7 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) diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index 44fe7eabadde883db852b880eb997444f3f48050..3df87ed4f603956a653cec692031dee94639de16 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -130,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 diff --git a/remoting/zookeeper/listener_test.go b/remoting/zookeeper/listener_test.go index 845c9a122700724d5b1c34a0a3d798db787837fc..8b133336e7242da6505132836748880259bf5e1d 100644 --- a/remoting/zookeeper/listener_test.go +++ b/remoting/zookeeper/listener_test.go @@ -18,6 +18,7 @@ package zookeeper import ( + "sync" "testing" "time" ) @@ -86,32 +87,36 @@ func TestListener(t *testing.T) { dubbo.service.com.ikurento.user.UserProvider.warmup=100 dubbo.service.com.ikurento.user.UserProvider.cluster=failover ` - + var wait sync.WaitGroup ts, client, event := initZkData(t) defer ts.Stop() client.Wait.Add(1) + wait.Add(1) go client.HandleZkEvent(event) listener := NewZkEventListener(client) - dataListener := &mockDataListener{client: client, changedData: changedData} + dataListener := &mockDataListener{client: client, changedData: changedData, wait: &wait} listener.ListenServiceEvent("/dubbo", dataListener) _, err := client.Conn.Set("/dubbo/dubbo.properties", []byte(changedData), 1) assert.NoError(t, err) - client.Wait.Wait() + wait.Wait() assert.Equal(t, changedData, dataListener.eventList[1].Content) + client.Close() + } type mockDataListener struct { eventList []remoting.Event client *ZookeeperClient changedData string + wait *sync.WaitGroup } func (m *mockDataListener) DataChange(eventType remoting.Event) bool { logger.Info(eventType) m.eventList = append(m.eventList, eventType) if eventType.Content == m.changedData { - m.client.Close() + m.wait.Done() } return true }