diff --git a/client/client_transport.go b/client/client_transport.go index 0400511ae168ed9ca488c67e0e4799ba289e590a..61e3ad511bc965fa0b29c72866c9ff0cda31426b 100644 --- a/client/client_transport.go +++ b/client/client_transport.go @@ -1,6 +1,5 @@ package client - import ( "context" ) @@ -18,7 +17,6 @@ type Transport interface { // Request ////////////////////////////////////////////// -type Request interface { +type Request interface { ServiceConfig() registry.DefaultServiceConfig } - diff --git a/client/invoker/invoker.go b/client/invoker/invoker.go index 3d38ff3dbc51da961da0f800ab639f7635cc9f3d..a80f509535cb375be74631cae91722c41f7fd704 100644 --- a/client/invoker/invoker.go +++ b/client/invoker/invoker.go @@ -12,11 +12,11 @@ import ( ) import ( + "github.com/dubbo/dubbo-go/client" "github.com/dubbo/dubbo-go/client/selector" "github.com/dubbo/dubbo-go/dubbo" "github.com/dubbo/dubbo-go/jsonrpc" "github.com/dubbo/dubbo-go/registry" - "github.com/dubbo/dubbo-go/client" ) const RegistryConnDelay = 3 diff --git a/dubbo/client.go b/dubbo/client.go index 286bac1e864282e5e93d31ba34eaccd542d80699..038bce15e6c9ac458559f1607c447c5719208805 100644 --- a/dubbo/client.go +++ b/dubbo/client.go @@ -157,12 +157,11 @@ func (c *Client) call(ct CallType, addr string, svcUrl registry.ServiceURL, meth p.Service.Version = svcUrl.Version p.Service.Method = method p.Service.Timeout = opts.RequestTimeout - //if opts.SerialID == 0 || opts.SerialID == 1 || opts.SerialID == 3 || opts.SerialID == 4 || opts.SerialID == 5 || opts.SerialID == 6 || - // opts.SerialID == 7 || pts.SerialID == 8 { - // p.Header.SerialID = byte(S_Dubbo) - //} else { - p.Header.SerialID = byte(opts.SerialID) - //} + if opts.SerialID == 0 { + p.Header.SerialID = byte(S_Dubbo) + } else { + p.Header.SerialID = byte(opts.SerialID) + } p.Body = args var rsp *PendingResponse @@ -236,7 +235,7 @@ func (c *Client) transfer(session getty.Session, pkg *DubboPackage, pkg = &DubboPackage{} pkg.Body = []interface{}{} pkg.Header.Type = hessian.Heartbeat - //pkg.Header.SerialID = byte(4) + pkg.Header.SerialID = byte(S_Dubbo) } else { pkg.Header.Type = hessian.Request } diff --git a/dubbo/codec.go b/dubbo/codec.go index 0556afcfb32143c238a191c288b6f56d69279bd1..d1a96940a4606377f6e42a122bbb8f91c789c556 100644 --- a/dubbo/codec.go +++ b/dubbo/codec.go @@ -56,15 +56,19 @@ func (p *DubboPackage) Marshal() (*bytes.Buffer, error) { return bytes.NewBuffer(pkg), nil } -func (p *DubboPackage) Unmarshal(buf *bytes.Buffer, pkgType hessian.PackgeType) error { +func (p *DubboPackage) Unmarshal(buf *bytes.Buffer) error { codec := hessian.NewHessianCodec(bufio.NewReader(buf)) // read header - err := codec.ReadHeader(&p.Header, pkgType) + err := codec.ReadHeader(&p.Header) if err != nil { return jerrors.Trace(err) } + if p.Header.Type&hessian.Heartbeat != 0x00 { + return nil + } + // read body err = codec.ReadBody(p.Body) return jerrors.Trace(err) diff --git a/dubbo/config.go b/dubbo/config.go index f806e0042d83b8f2a59fb5d6915bfe8c9814fc85..723d1c75fb099fa0ab6081bb1b72ceb88dfea704 100644 --- a/dubbo/config.go +++ b/dubbo/config.go @@ -1,6 +1,7 @@ package dubbo import ( + "github.com/dubbo/dubbo-go/server" "time" ) @@ -31,11 +32,12 @@ type ( // Config holds supported types by the multiconfig package ServerConfig struct { + server.ServerConfig // 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"` + //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"` @@ -53,9 +55,9 @@ type ( // Config holds supported types by the multiconfig package ClientConfig struct { // local address - AppName string `default:"rpc-client" yaml:"app_name" json:"app_name,omitempty"` - Host string `default:"127.0.0.1" yaml:"host" json:"host,omitempty"` - ProfilePort int `default:"10086" yaml:"profile_port" json:"profile_port,omitempty"` + //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"` // session pool ConnectionNum int `default:"16" yaml:"connection_number" json:"connection_number,omitempty"` diff --git a/dubbo/listener.go b/dubbo/listener.go index 83b2e5f40179c03756cfabdfe0b0f93629677cec..ee2c0fe991a76ca2d67a804425edeef68bef9aad 100644 --- a/dubbo/listener.go +++ b/dubbo/listener.go @@ -1,6 +1,9 @@ package dubbo import ( + "context" + "reflect" + "sync" "time" ) @@ -54,11 +57,11 @@ func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) { return } - if p.Header.Type == hessian.Heartbeat { + if p.Header.Type&hessian.Heartbeat != 0x00 { log.Debug("get rpc heartbeat response{header: %#v, body: %#v}", p.Header, p.Body) return } - log.Debug("get rpc response{header: %#v, header: %#v}", p.Header, p.Body) + log.Debug("get rpc response{header: %#v, body: %#v}", p.Header, p.Body) h.conn.updateSession(session) @@ -94,3 +97,190 @@ func (h *RpcClientHandler) OnCron(session getty.Session) { h.conn.pool.rpcClient.heartbeat(session) } + +//////////////////////////////////////////// +// RpcServerHandler +//////////////////////////////////////////// + +type RpcServerHandler struct { + maxSessionNum int + sessionTimeout time.Duration + sessionMap map[getty.Session]*rpcSession + rwlock sync.RWMutex +} + +func NewRpcServerHandler(maxSessionNum int, sessionTimeout time.Duration) *RpcServerHandler { + return &RpcServerHandler{ + maxSessionNum: maxSessionNum, + sessionTimeout: sessionTimeout, + sessionMap: make(map[getty.Session]*rpcSession), + } +} + +func (h *RpcServerHandler) OnOpen(session getty.Session) error { + var err error + h.rwlock.RLock() + if h.maxSessionNum <= len(h.sessionMap) { + err = errTooManySessions + } + h.rwlock.RUnlock() + if err != nil { + return jerrors.Trace(err) + } + + log.Info("got session:%s", session.Stat()) + h.rwlock.Lock() + h.sessionMap[session] = &rpcSession{session: session} + h.rwlock.Unlock() + return nil +} + +func (h *RpcServerHandler) OnError(session getty.Session, err error) { + log.Info("session{%s} got error{%v}, will be closed.", session.Stat(), err) + h.rwlock.Lock() + delete(h.sessionMap, session) + h.rwlock.Unlock() +} + +func (h *RpcServerHandler) OnClose(session getty.Session) { + log.Info("session{%s} is closing......", session.Stat()) + h.rwlock.Lock() + delete(h.sessionMap, session) + h.rwlock.Unlock() +} + +func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { + h.rwlock.Lock() + if _, ok := h.sessionMap[session]; ok { + h.sessionMap[session].reqNum++ + } + h.rwlock.Unlock() + + p, ok := pkg.(*DubboPackage) + if !ok { + log.Error("illegal packge{%#v}", pkg) + return + } + p.Header.ResponseStatus = hessian.Response_OK + + // heartbeat + if p.Header.Type&hessian.Heartbeat != 0x00 { + log.Debug("get rpc heartbeat request{header: %#v, service: %#v, body: %#v}", p.Header, p.Service, p.Body) + h.reply(session, p, hessian.Heartbeat) + return + } + + // twoway + if p.Header.Type&hessian.Request_TwoWay == 0x00 { + h.reply(session, p, hessian.Response) + h.callService(p, nil) + return + } + + h.callService(p, nil) + h.reply(session, p, hessian.Response) +} + +func (h *RpcServerHandler) OnCron(session getty.Session) { + var ( + flag bool + active time.Time + ) + + h.rwlock.RLock() + if _, ok := h.sessionMap[session]; ok { + active = session.GetActive() + if h.sessionTimeout.Nanoseconds() < time.Since(active).Nanoseconds() { + flag = true + log.Warn("session{%s} timeout{%s}, reqNum{%d}", + session.Stat(), time.Since(active).String(), h.sessionMap[session].reqNum) + } + } + h.rwlock.RUnlock() + + if flag { + h.rwlock.Lock() + delete(h.sessionMap, session) + h.rwlock.Unlock() + session.Close() + } +} + +func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) { + + defer func() { + if e := recover(); e != nil { + req.Header.ResponseStatus = hessian.Response_BAD_REQUEST + if err, ok := e.(error); ok { + log.Error("callService panic: %#v", err) + req.Body = e.(error) + } else if err, ok := e.(string); ok { + log.Error("callService panic: %#v", jerrors.New(err)) + req.Body = jerrors.New(err) + } else { + log.Error("callService panic: %#v", e) + req.Body = e + } + } + }() + + svc := req.Body.(map[string]interface{})["service"].(*service) + method := svc.method[req.Service.Method] + + // prepare argv + var argv reflect.Value + argIsValue := false // if true, need to indirect before calling. + if method.ArgType.Kind() == reflect.Ptr { + argv = reflect.New(method.ArgType.Elem()) + } else { + argv = reflect.New(method.ArgType) + argIsValue = true + } + argvTmp := argv.Interface() + argvTmp = req.Body.(map[string]interface{})["args"] // type is []interface + if argIsValue { + argv = argv.Elem() + } + + // prepare replyv + replyv := reflect.New(method.ReplyType.Elem()) + var returnValues []reflect.Value + if method.CtxType == nil { + returnValues = method.method.Func.Call([]reflect.Value{svc.rcvr, reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())}) + } else { + if contextv := reflect.ValueOf(ctx); contextv.IsValid() { + returnValues = method.method.Func.Call([]reflect.Value{svc.rcvr, contextv, reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())}) + } else { + returnValues = method.method.Func.Call([]reflect.Value{svc.rcvr, reflect.Zero(method.CtxType), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())}) + } + } + + // The return value for the method is an error. + if retErr := returnValues[0].Interface(); retErr != nil { + req.Header.ResponseStatus = hessian.Response_SERVER_ERROR + req.Body = retErr.(error) + } else { + req.Body = replyv.Interface() + } +} + +func (h *RpcServerHandler) reply(session getty.Session, req *DubboPackage, tp hessian.PackgeType) { + resp := &DubboPackage{ + Header: hessian.DubboHeader{ + SerialID: req.Header.SerialID, + Type: tp, + ID: req.Header.ID, + ResponseStatus: req.Header.ResponseStatus, + }, + } + + if req.Header.Type&hessian.Request != 0x00 { + resp.Body = req.Body + } else { + resp.Body = nil + } + + if err := session.WritePkg(resp, 10*time.Second); err != nil { + log.Error("WritePkg error: %#v, %#v", jerrors.Trace(err), req.Header) + } +} diff --git a/dubbo/readwriter.go b/dubbo/readwriter.go index 9db59456c78ead7f95e238fe2ad32cf12bc892c0..e14cf201009a98992d57ed1e714a7cb3252bd862 100644 --- a/dubbo/readwriter.go +++ b/dubbo/readwriter.go @@ -2,12 +2,12 @@ package dubbo import ( "bytes" + "reflect" ) import ( "github.com/AlexStocks/getty" log "github.com/AlexStocks/log4go" - "github.com/dubbogo/hessian2" jerrors "github.com/juju/errors" ) @@ -29,9 +29,9 @@ func (p *RpcClientPackageHandler) Read(ss getty.Session, data []byte) (interface } buf := bytes.NewBuffer(data) - err := pkg.Unmarshal(buf, hessian.Response) + err := pkg.Unmarshal(buf) if err != nil { - pkg.Err = jerrors.Trace(err) + pkg.Err = jerrors.Trace(err) // client will get this err return pkg, len(data), nil } @@ -60,24 +60,77 @@ func (p *RpcClientPackageHandler) Write(ss getty.Session, pkg interface{}) error type RpcServerPackageHandler struct { server *Server + srvMap serviceMap } -func NewRpcServerPackageHandler(server *Server) *RpcServerPackageHandler { +func NewRpcServerPackageHandler(server *Server, srvMap serviceMap) *RpcServerPackageHandler { return &RpcServerPackageHandler{ server: server, + srvMap: srvMap, } } func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) { pkg := &DubboPackage{ - Body: nil, + Body: make([]interface{}, 7), + } + + buf := bytes.NewBuffer(data) + err := pkg.Unmarshal(buf) + if err != nil { + return nil, 0, jerrors.Trace(err) + } + // convert params of request + req := pkg.Body.([]interface{}) // length of body should be 7 + if len(req) > 0 { + var dubboVersion, argsTypes string + var args []interface{} + var attachments map[interface{}]interface{} + if req[0] != nil { + dubboVersion = req[0].(string) + } + if req[1] != nil { + pkg.Service.Target = req[1].(string) + } + if req[2] != nil { + pkg.Service.Version = req[2].(string) + } + if req[3] != nil { + pkg.Service.Method = req[3].(string) + } + if req[4] != nil { + argsTypes = req[4].(string) + } + if req[5] != nil { + args = req[5].([]interface{}) + } + if req[6] != nil { + attachments = req[6].(map[interface{}]interface{}) + } + pkg.Body = map[string]interface{}{ + "dubboVersion": dubboVersion, + "argsTypes": argsTypes, + "args": args, + "service": p.srvMap[pkg.Service.Target], + "attachments": attachments, + } } - // todo: return pkg, len(data), nil } func (p *RpcServerPackageHandler) Write(ss getty.Session, pkg interface{}) error { - // todo: - return nil + res, ok := pkg.(*DubboPackage) + if !ok { + log.Error("illegal pkg:%+v\n, it is %+v", pkg, reflect.TypeOf(pkg)) + return jerrors.New("invalid rpc response") + } + + buf, err := res.Marshal() + if err != nil { + log.Warn("binary.Write(res{%#v}) = err{%#v}", res, jerrors.ErrorStack(err)) + return jerrors.Trace(err) + } + + return jerrors.Trace(ss.WriteBytes(buf.Bytes())) } diff --git a/dubbo/rpc.go b/dubbo/rpc.go index efb0f36c9b3c688f45a15139997c614071607f4d..f20fc9603eeb630a525ee8a87e638eec95aead96 100644 --- a/dubbo/rpc.go +++ b/dubbo/rpc.go @@ -23,15 +23,16 @@ type GettyRPCService interface { type methodType struct { sync.Mutex method reflect.Method + CtxType reflect.Type // type of the request context ArgType reflect.Type ReplyType reflect.Type } type service struct { - name string - rcvr reflect.Value - typ reflect.Type - method map[string]*methodType + name string + rcvr reflect.Value + rcvrType reflect.Type + method map[string]*methodType } // Is this an exported - upper case - name @@ -51,56 +52,68 @@ func isExportedOrBuiltinType(t reflect.Type) bool { } // suitableMethods returns suitable Rpc methods of typ -func suitableMethods(typ reflect.Type) map[string]*methodType { +func suitableMethods(typ reflect.Type) (string, map[string]*methodType) { methods := make(map[string]*methodType) + mts := "" for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) - mtype := method.Type - mname := method.Name - // Method must be exported. - if method.PkgPath != "" { - continue - } - // service Method needs three ins: receiver, *args, *reply. - // notify Method needs two ins: receiver, *args. - mInNum := mtype.NumIn() - if mInNum != 2 && mInNum != 3 { - log.Warn("method %s has wrong number of ins %d which should be "+ - "2(notify method) or 3(serive method)", mname, mtype.NumIn()) - continue - } - // First arg need not be a pointer. - argType := mtype.In(1) - if !isExportedOrBuiltinType(argType) { - log.Error("method{%s} argument type not exported{%v}", mname, argType) - continue + if mt := suiteMethod(method); mt != nil { + methods[method.Name] = mt + mts += method.Name + "," } + } + return mts, methods +} - var replyType reflect.Type - if mInNum == 3 { - // Second arg must be a pointer. - replyType = mtype.In(2) - if replyType.Kind() != reflect.Ptr { - log.Error("method{%s} reply type not a pointer{%v}", mname, replyType) - continue - } - // Reply type must be exported. - if !isExportedOrBuiltinType(replyType) { - log.Error("method{%s} reply type not exported{%v}", mname, replyType) - continue - } - } - // Method needs one out. - if mtype.NumOut() != 1 { - log.Error("method{%s} has wrong number of out parameters{%d}", mname, mtype.NumOut()) - continue - } - // The return type of the method must be error. - if returnType := mtype.Out(0); returnType != typeOfError { - log.Error("method{%s}'s return type{%s} is not error", mname, returnType.String()) - continue - } - methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType} +// suiteMethod returns a suitable Rpc methodType +func suiteMethod(method reflect.Method) *methodType { + mtype := method.Type + mname := method.Name + + // Method must be exported. + if method.PkgPath != "" { + return nil } - return methods + + var replyType, argType, ctxType reflect.Type + switch mtype.NumIn() { + case 3: + argType = mtype.In(1) + replyType = mtype.In(2) + case 4: + ctxType = mtype.In(1) + argType = mtype.In(2) + replyType = mtype.In(3) + default: + log.Error("method %s of mtype %v has wrong number of in parameters %d; needs exactly 3/4", + mname, mtype, mtype.NumIn()) + return nil + } + // First arg need not be a pointer. + if !isExportedOrBuiltinType(argType) { + log.Error("argument type of method %q is not exported %v", mname, argType) + return nil + } + // Second arg must be a pointer. + if replyType.Kind() != reflect.Ptr { + log.Error("reply type of method %q is not a pointer %v", mname, replyType) + return nil + } + // Reply type must be exported. + if !isExportedOrBuiltinType(replyType) { + log.Error("reply type of method %s not exported{%v}", mname, replyType) + return nil + } + // Method needs one out. + if mtype.NumOut() != 1 { + log.Error("method %q has %d out parameters; needs exactly 1", mname, mtype.NumOut()) + return nil + } + // The return type of the method must be error. + if returnType := mtype.Out(0); returnType != typeOfError { + log.Error("return type %s of method %q is not error", returnType, mname) + return nil + } + + return &methodType{method: method, ArgType: argType, ReplyType: replyType, CtxType: ctxType} } diff --git a/dubbo/server.go b/dubbo/server.go index fd16495b945a5d9cd96985b52df7df299ed87d36..efcb83861f84e88c447041a8dc9d4131dc183439 100644 --- a/dubbo/server.go +++ b/dubbo/server.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "reflect" + "strconv" ) import ( @@ -13,62 +14,168 @@ import ( jerrors "github.com/juju/errors" ) -type Server struct { - conf ServerConfig - serviceMap map[string]*service - tcpServerList []getty.Server +import ( + "github.com/dubbo/dubbo-go/registry" +) + +type Option func(*Options) + +type Options struct { + Registry registry.Registry + ConfList []ServerConfig + ServiceConfList []registry.DefaultServiceConfig } -func NewServer(conf *ServerConfig) (*Server, error) { - if err := conf.CheckValidity(); err != nil { - return nil, jerrors.Trace(err) +func newOptions(opt ...Option) Options { + opts := Options{} + for _, o := range opt { + o(&opts) } - s := &Server{ - serviceMap: make(map[string]*service), - conf: *conf, + if opts.Registry == nil { + panic("server.Options.Registry is nil") } - return s, nil + return opts } -func (s *Server) Register(rcvr GettyRPCService) error { - svc := &service{ - typ: reflect.TypeOf(rcvr), - rcvr: reflect.ValueOf(rcvr), - name: reflect.Indirect(reflect.ValueOf(rcvr)).Type().Name(), - // Install the methods - method: suitableMethods(reflect.TypeOf(rcvr)), - } - if svc.name == "" { - s := "rpc.Register: no service name for type " + svc.typ.String() - log.Error(s) - return jerrors.New(s) +// Registry used for discovery +func Registry(r registry.Registry) Option { + return func(o *Options) { + o.Registry = r } - if !isExported(svc.name) { - s := "rpc.Register: type " + svc.name + " is not exported" - log.Error(s) - return jerrors.New(s) - } - if _, present := s.serviceMap[svc.name]; present { - return jerrors.New("rpc: service already defined: " + svc.name) +} + +func ConfList(confList []ServerConfig) Option { + return func(o *Options) { + o.ConfList = confList + for i := 0; i < len(o.ConfList); i++ { + if err := o.ConfList[i].CheckValidity(); err != nil { + log.Error("ServerConfig check failed: ", err) + o.ConfList = []ServerConfig{} + return + } + if o.ConfList[i].IP == "" { + o.ConfList[i].IP, _ = gxnet.GetLocalIP() + } + } } +} - if len(svc.method) == 0 { - // To help the user, see if a pointer receiver would work. - method := suitableMethods(reflect.PtrTo(svc.typ)) - str := "rpc.Register: type " + svc.name + " has no exported methods of suitable type" - if len(method) != 0 { - str = "rpc.Register: type " + svc.name + " has no exported methods of suitable type (" + - "hint: pass a pointer to value of that type)" +func ServiceConfList(confList []registry.DefaultServiceConfig) Option { + return func(o *Options) { + o.ServiceConfList = confList + if o.ServiceConfList == nil { + o.ServiceConfList = []registry.DefaultServiceConfig{} } - log.Error(str) + } +} + +type serviceMap map[string]*service - return jerrors.New(str) +type Server struct { + opts Options + indexOfConfList int + srvs []serviceMap + tcpServerList []getty.Server +} + +func NewServer(opts ...Option) *Server { + options := newOptions(opts...) + num := len(options.ConfList) + servers := make([]serviceMap, len(options.ConfList)) + + for i := 0; i < num; i++ { + servers[i] = map[string]*service{} } - s.serviceMap[svc.name] = svc + s := &Server{ + opts: options, + srvs: servers, + } + + return s +} + +// Register export services and register with the registry +func (s *Server) Register(rcvr GettyRPCService) error { + + var serviceConf registry.ProviderServiceConfig + + opts := s.opts + + serviceConf.Service = rcvr.Service() + serviceConf.Version = rcvr.Version() + + flag := false + serviceNum := len(opts.ServiceConfList) + serverNum := len(opts.ConfList) + for i := 0; i < serviceNum; i++ { + if opts.ServiceConfList[i].Service == serviceConf.Service && + opts.ServiceConfList[i].Version == serviceConf.Version { + + serviceConf.Protocol = opts.ServiceConfList[i].Protocol + serviceConf.Group = opts.ServiceConfList[i].Group + + for j := 0; j < serverNum; j++ { + if opts.ConfList[j].Protocol == serviceConf.Protocol { + rcvrName := reflect.Indirect(reflect.ValueOf(rcvr)).Type().Name() + svc := &service{ + rcvrType: reflect.TypeOf(rcvr), + rcvr: reflect.ValueOf(rcvr), + } + if rcvrName == "" { + s := "rpc.Register: no service name for type " + svc.rcvrType.String() + log.Error(s) + return jerrors.New(s) + } + if !isExported(rcvrName) { + s := "rpc.Register: type " + rcvrName + " is not exported" + log.Error(s) + return jerrors.New(s) + } + + svc.name = rcvr.Service() // service name is from 'Service()' + if _, present := s.srvs[j][svc.name]; present { + return jerrors.New("rpc: service already defined: " + svc.name) + } + + // Install the methods + mts, methods := suitableMethods(svc.rcvrType) + svc.method = methods + + if len(svc.method) == 0 { + // To help the user, see if a pointer receiver would work. + mts, methods = suitableMethods(reflect.PtrTo(svc.rcvrType)) + str := "rpc.Register: type " + rcvrName + " has no exported methods of suitable type" + if len(methods) != 0 { + str = "rpc.Register: type " + rcvrName + " has no exported methods of suitable type (" + + "hint: pass a pointer to value of that type)" + } + log.Error(str) + + return jerrors.New(str) + } + + s.srvs[j][svc.name] = svc + + serviceConf.Methods = mts + serviceConf.Path = opts.ConfList[j].Address() + + err := opts.Registry.Register(serviceConf) + if err != nil { + return err + } + flag = true + } + } + } + } + if !flag { + return jerrors.Errorf("fail to register Handler{service:%s, version:%s}", + serviceConf.Service, serviceConf.Version) + } return nil } @@ -77,8 +184,9 @@ func (s *Server) newSession(session getty.Session) error { ok bool tcpConn *net.TCPConn ) + conf := s.opts.ConfList[s.indexOfConfList] - if s.conf.GettySessionParam.CompressEncoding { + if conf.GettySessionParam.CompressEncoding { session.SetCompressType(getty.CompressZip) } @@ -86,24 +194,24 @@ func (s *Server) newSession(session getty.Session) error { panic(fmt.Sprintf("%s, session.conn{%#v} is not tcp connection\n", session.Stat(), session.Conn())) } - tcpConn.SetNoDelay(s.conf.GettySessionParam.TcpNoDelay) - tcpConn.SetKeepAlive(s.conf.GettySessionParam.TcpKeepAlive) - if s.conf.GettySessionParam.TcpKeepAlive { - tcpConn.SetKeepAlivePeriod(s.conf.GettySessionParam.keepAlivePeriod) + tcpConn.SetNoDelay(conf.GettySessionParam.TcpNoDelay) + tcpConn.SetKeepAlive(conf.GettySessionParam.TcpKeepAlive) + if conf.GettySessionParam.TcpKeepAlive { + tcpConn.SetKeepAlivePeriod(conf.GettySessionParam.keepAlivePeriod) } - tcpConn.SetReadBuffer(s.conf.GettySessionParam.TcpRBufSize) - tcpConn.SetWriteBuffer(s.conf.GettySessionParam.TcpWBufSize) - - session.SetName(s.conf.GettySessionParam.SessionName) - session.SetMaxMsgLen(s.conf.GettySessionParam.MaxMsgLen) - session.SetPkgHandler(NewRpcServerPackageHandler(s)) - //session.SetEventListener(NewRpcServerHandler(s.conf.SessionNumber, s.conf.sessionTimeout)) - session.SetRQLen(s.conf.GettySessionParam.PkgRQSize) - session.SetWQLen(s.conf.GettySessionParam.PkgWQSize) - session.SetReadTimeout(s.conf.GettySessionParam.tcpReadTimeout) - session.SetWriteTimeout(s.conf.GettySessionParam.tcpWriteTimeout) - session.SetCronPeriod((int)(s.conf.sessionTimeout.Nanoseconds() / 1e6)) - session.SetWaitTime(s.conf.GettySessionParam.waitTimeout) + tcpConn.SetReadBuffer(conf.GettySessionParam.TcpRBufSize) + tcpConn.SetWriteBuffer(conf.GettySessionParam.TcpWBufSize) + + session.SetName(conf.GettySessionParam.SessionName) + session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen) + session.SetPkgHandler(NewRpcServerPackageHandler(s, s.srvs[s.indexOfConfList])) + session.SetEventListener(NewRpcServerHandler(conf.SessionNumber, conf.sessionTimeout)) + session.SetRQLen(conf.GettySessionParam.PkgRQSize) + session.SetWQLen(conf.GettySessionParam.PkgWQSize) + session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout) + session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout) + session.SetCronPeriod((int)(conf.sessionTimeout.Nanoseconds() / 1e6)) + session.SetWaitTime(conf.GettySessionParam.waitTimeout) log.Debug("app accepts new session:%s\n", session.Stat()) return nil @@ -112,23 +220,24 @@ func (s *Server) newSession(session getty.Session) error { func (s *Server) Start() { var ( addr string - portList []string tcpServer getty.Server ) - portList = s.conf.Ports - if len(portList) == 0 { - panic("portList is nil") + if len(s.opts.ConfList) == 0 { + panic("ConfList is nil") } - for _, port := range portList { - addr = gxnet.HostAddress2(s.conf.Host, port) + + for i := 0; i < len(s.opts.ConfList); i++ { + addr = gxnet.HostAddress2(s.opts.ConfList[i].IP, strconv.Itoa(s.opts.ConfList[i].Port)) tcpServer = getty.NewTCPServer( getty.WithLocalAddress(addr), ) + s.indexOfConfList = i tcpServer.RunEventLoop(s.newSession) log.Debug("s bind addr{%s} ok!", addr) s.tcpServerList = append(s.tcpServerList, tcpServer) } + } func (s *Server) Stop() { diff --git a/examples/dubbo/go-client/app/test.go b/examples/dubbo/go-client/app/test.go index aafd05db595a32a75e0279a7c178c083cc0cc28f..5a884570882378fcb2aa4660f23e7ec2545a7f17 100644 --- a/examples/dubbo/go-client/app/test.go +++ b/examples/dubbo/go-client/app/test.go @@ -53,7 +53,6 @@ func testDubborpc(clientConfig *examples.ClientConfig, userKey string) { hessian.RegisterJavaEnum(Gender(MAN)) hessian.RegisterJavaEnum(Gender(WOMAN)) hessian.RegisterPOJO(&DubboUser{}) - hessian.RegisterPOJO(&Response{}) user = new(DubboUser) defer clientInvoker.DubboClient.Close() diff --git a/examples/dubbo/go-client/app/user.go b/examples/dubbo/go-client/app/user.go index 210335cbc5511fcfe4d5f9403ebe44db6da96a8f..bc2212f532e9e4d349d92df6fe55d2432931b07a 100644 --- a/examples/dubbo/go-client/app/user.go +++ b/examples/dubbo/go-client/app/user.go @@ -2,30 +2,14 @@ package main import ( "fmt" - "github.com/dubbogo/hessian2" "strconv" "time" ) import ( - "github.com/AlexStocks/goext/time" + "github.com/dubbogo/hessian2" ) -type JsonRPCUser struct { - ID string `json:"id"` - Name string `json:"name"` - Age int64 `json:"age"` - Time int64 `json:"time"` - Sex string `json:"sex"` -} - -func (u JsonRPCUser) String() string { - return fmt.Sprintf( - "User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}", - u.ID, u.Name, u.Age, gxtime.YMDPrint(int(u.Time), 0), u.Sex, - ) -} - type Gender hessian.JavaEnum const ( @@ -83,20 +67,3 @@ func (u DubboUser) String() string { func (DubboUser) JavaClassName() string { return "com.ikurento.user.User" } - -type Response struct { - Status int - Err string - Data int -} - -func (r Response) String() string { - return fmt.Sprintf( - "Response{Status:%d, Err:%s, Data:%d}", - r.Status, r.Err, r.Data, - ) -} - -func (Response) JavaClassName() string { - return "com.ikurento.user.Response" -} diff --git a/examples/dubbo/go-server/app/config.go b/examples/dubbo/go-server/app/config.go new file mode 100644 index 0000000000000000000000000000000000000000..ff69320cb2f11f08e9f6e375a4a7538ede07d430 --- /dev/null +++ b/examples/dubbo/go-server/app/config.go @@ -0,0 +1,115 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "time" +) + +import ( + "github.com/AlexStocks/goext/log" + log "github.com/AlexStocks/log4go" + jerrors "github.com/juju/errors" + yaml "gopkg.in/yaml.v2" +) + +import ( + "github.com/dubbo/dubbo-go/registry" + "github.com/dubbo/dubbo-go/registry/zookeeper" + "github.com/dubbo/dubbo-go/server" +) + +const ( + APP_CONF_FILE string = "APP_CONF_FILE" + APP_LOG_CONF_FILE string = "APP_LOG_CONF_FILE" +) + +var ( + conf *ServerConfig +) + +type ( + ServerConfig struct { + // pprof + Pprof_Enabled bool `default:"false" yaml:"pprof_enabled" json:"pprof_enabled,omitempty"` + Pprof_Port int `default:"10086" yaml:"pprof_port" json:"pprof_port,omitempty"` + + // transport & registry + Transport string `default:"http" yaml:"transport" json:"transport,omitempty"` + NetTimeout string `default:"100ms" yaml:"net_timeout" json:"net_timeout,omitempty"` // in ms + netTimeout time.Duration + // application + Application_Config registry.ApplicationConfig `yaml:"application_config" json:"application_config,omitempty"` + // Registry_Address string `default:"192.168.35.3:2181"` + Registry string `default:"zookeeper" yaml:"registry" json:"registry,omitempty"` + ZkRegistryConfig zookeeper.ZkRegistryConfig `yaml:"zk_registry_config" json:"zk_registry_config,omitempty"` + Service_List []registry.DefaultServiceConfig `yaml:"service_list" json:"service_list,omitempty"` + Server_List []server.ServerConfig `yaml:"server_list" json:"server_list,omitempty"` + } +) + +func initServerConf() *ServerConfig { + var ( + err error + confFile string + ) + + confFile = os.Getenv(APP_CONF_FILE) + if confFile == "" { + panic(fmt.Sprintf("application configure file name is nil")) + return nil + } + if path.Ext(confFile) != ".yml" { + panic(fmt.Sprintf("application configure file name{%v} suffix must be .yml", confFile)) + return nil + } + + conf = &ServerConfig{} + confFileStream, err := ioutil.ReadFile(confFile) + if err != nil { + panic(fmt.Sprintf("ioutil.ReadFile(file:%s) = error:%s", confFile, jerrors.ErrorStack(err))) + return nil + } + err = yaml.Unmarshal(confFileStream, conf) + if err != nil { + panic(fmt.Sprintf("yaml.Unmarshal() = error:%s", jerrors.ErrorStack(err))) + return nil + } + if conf.netTimeout, err = time.ParseDuration(conf.NetTimeout); err != nil { + panic(fmt.Sprintf("time.ParseDuration(NetTimeout:%#v) = error:%s", conf.NetTimeout, err)) + return nil + } + if conf.ZkRegistryConfig.Timeout, err = time.ParseDuration(conf.ZkRegistryConfig.TimeoutStr); err != nil { + panic(fmt.Sprintf("time.ParseDuration(Registry_Config.Timeout:%#v) = error:%s", + conf.ZkRegistryConfig.TimeoutStr, err)) + return nil + } + + gxlog.CInfo("config{%#v}\n", conf) + + return conf +} + +func configInit() error { + var ( + confFile string + ) + + initServerConf() + + confFile = os.Getenv(APP_LOG_CONF_FILE) + if confFile == "" { + panic(fmt.Sprintf("log configure file name is nil")) + return nil + } + if path.Ext(confFile) != ".xml" { + panic(fmt.Sprintf("log configure file name{%v} suffix must be .xml", confFile)) + return nil + } + + log.LoadConfiguration(confFile) + + return nil +} diff --git a/examples/dubbo/go-server/app/server.go b/examples/dubbo/go-server/app/server.go new file mode 100644 index 0000000000000000000000000000000000000000..64c996a6af63b58742d75f767080145e714bb965 --- /dev/null +++ b/examples/dubbo/go-server/app/server.go @@ -0,0 +1,175 @@ +package main + +import ( + "fmt" + "net/http" + _ "net/http/pprof" + "os" + "os/signal" + "strconv" + "syscall" +) + +import ( + "github.com/AlexStocks/goext/net" + "github.com/AlexStocks/goext/time" + log "github.com/AlexStocks/log4go" + "github.com/dubbogo/hessian2" + jerrors "github.com/juju/errors" +) + +import ( + "github.com/dubbo/dubbo-go/dubbo" + "github.com/dubbo/dubbo-go/plugins" + "github.com/dubbo/dubbo-go/registry" + "github.com/dubbo/dubbo-go/registry/zookeeper" +) + +var ( + survivalTimeout = int(3e9) + servo *dubbo.Server +) + +func main() { + var ( + err error + ) + + err = configInit() + if err != nil { + log.Error("configInit() = error{%#v}", err) + return + } + initProfiling() + + hessian.RegisterJavaEnum(Gender(MAN)) + hessian.RegisterJavaEnum(Gender(WOMAN)) + hessian.RegisterPOJO(&DubboUser{}) + + servo = initServer() + err = servo.Register(&UserProvider{}) + if err != nil { + panic(err) + return + } + servo.Start() + + initSignal() +} + +func initServer() *dubbo.Server { + var ( + srv *dubbo.Server + ) + + if conf == nil { + panic(fmt.Sprintf("conf is nil")) + return nil + } + + // registry + + regs, err := plugins.PluggableRegistries[conf.Registry]( + registry.WithDubboType(registry.PROVIDER), + registry.WithApplicationConf(conf.Application_Config), + zookeeper.WithRegistryConf(conf.ZkRegistryConfig), + ) + + if err != nil || regs == nil { + panic(fmt.Sprintf("fail to init registry.Registy, err:%s", jerrors.ErrorStack(err))) + return nil + } + + // generate server config + serverConfig := make([]dubbo.ServerConfig, len(conf.Server_List)) + for i := 0; i < len(conf.Server_List); i++ { + serverConfig[i] = dubbo.ServerConfig{ + SessionNumber: 700, + FailFastTimeout: "5s", + SessionTimeout: "20s", + GettySessionParam: dubbo.GettySessionParam{ + CompressEncoding: false, // 必须false + TcpNoDelay: true, + KeepAlivePeriod: "120s", + TcpRBufSize: 262144, + TcpKeepAlive: true, + TcpWBufSize: 65536, + PkgRQSize: 1024, + PkgWQSize: 512, + TcpReadTimeout: "1s", + TcpWriteTimeout: "5s", + WaitTimeout: "1s", + MaxMsgLen: 1024, + SessionName: "server", + }, + } + serverConfig[i].IP = conf.Server_List[i].IP + serverConfig[i].Port = conf.Server_List[i].Port + serverConfig[i].Protocol = conf.Server_List[i].Protocol + } + + // provider + srv = dubbo.NewServer( + dubbo.Registry(regs), + dubbo.ConfList(serverConfig), + dubbo.ServiceConfList(conf.Service_List), + ) + + return srv +} + +func uninitServer() { + if servo != nil { + servo.Stop() + } + log.Close() +} + +func initProfiling() { + if !conf.Pprof_Enabled { + return + } + const ( + PprofPath = "/debug/pprof/" + ) + var ( + err error + ip string + addr string + ) + + ip, err = gxnet.GetLocalIP() + if err != nil { + panic("cat not get local ip!") + } + addr = ip + ":" + strconv.Itoa(conf.Pprof_Port) + log.Info("App Profiling startup on address{%v}", addr+PprofPath) + + go func() { + log.Info(http.ListenAndServe(addr, nil)) + }() +} + +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 + log.Info("get signal %s", sig.String()) + switch sig { + case syscall.SIGHUP: + // reload() + default: + go gxtime.Future(survivalTimeout, func() { + log.Warn("app exit now by force...") + os.Exit(1) + }) + + // 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出 + uninitServer() + fmt.Println("provider app exit now...") + return + } + } +} diff --git a/examples/dubbo/go-server/app/user.go b/examples/dubbo/go-server/app/user.go new file mode 100644 index 0000000000000000000000000000000000000000..fa4f9f992eb8d50ee962527c6b7551125ec2da02 --- /dev/null +++ b/examples/dubbo/go-server/app/user.go @@ -0,0 +1,133 @@ +package main + +import ( + // "encoding/json" + "context" + "fmt" + "strconv" + "time" +) + +import ( + "github.com/AlexStocks/goext/log" + "github.com/dubbogo/hessian2" +) + +type Gender hessian.JavaEnum + +const ( + MAN hessian.JavaEnum = iota + WOMAN +) + +var genderName = map[hessian.JavaEnum]string{ + MAN: "MAN", + WOMAN: "WOMAN", +} + +var genderValue = map[string]hessian.JavaEnum{ + "MAN": MAN, + "WOMAN": WOMAN, +} + +func (g Gender) JavaClassName() string { + return "com.ikurento.user.Gender" +} + +func (g Gender) String() string { + s, ok := genderName[hessian.JavaEnum(g)] + if ok { + return s + } + + return strconv.Itoa(int(g)) +} + +func (g Gender) EnumValue(s string) hessian.JavaEnum { + v, ok := genderValue[s] + if ok { + return v + } + + return hessian.InvalidJavaEnum +} + +type ( + DubboUser struct { + // !!! Cannot define lowercase names of variable + Id string + Name string + Age int32 + Time time.Time + Sex Gender // 注意此处,java enum Object <--> go string + } + + UserProvider struct { + user map[string]DubboUser + } +) + +func (u DubboUser) String() string { + return fmt.Sprintf( + "User{Id:%s, Name:%s, Age:%d, Time:%s, Sex:%s}", + u.Id, u.Name, u.Age, u.Time, u.Sex, + ) +} + +func (DubboUser) JavaClassName() string { + return "com.ikurento.user.User" +} + +var ( + DefaultUser = DubboUser{ + Id: "0", Name: "Alex Stocks", Age: 31, + Sex: Gender(MAN), + } + + userMap = UserProvider{user: make(map[string]DubboUser)} +) + +func init() { + //DefaultUser.Sex = DefaultUser.sex.String() + userMap.user["A000"] = DefaultUser + userMap.user["A001"] = DubboUser{Id: "001", Name: "ZhangSheng", Age: 18, Sex: Gender(MAN)} + userMap.user["A002"] = DubboUser{Id: "002", Name: "Lily", Age: 20, Sex: Gender(WOMAN)} + userMap.user["A003"] = DubboUser{Id: "113", Name: "Moorse", Age: 30, Sex: Gender(WOMAN)} + for k, v := range userMap.user { + userMap.user[k] = v + } +} + +func (u *UserProvider) getUser(userId string) (*DubboUser, error) { + if user, ok := userMap.user[userId]; ok { + return &user, nil + } + + return nil, fmt.Errorf("invalid user id:%s", userId) +} + +/* + !!! req must be []interface{} +*/ +func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *DubboUser) error { + var ( + err error + user *DubboUser + ) + + gxlog.CInfo("req:%#v", req) + user, err = u.getUser(req[0].(string)) + if err == nil { + *rsp = *user + gxlog.CInfo("rsp:%#v", rsp) + } + return err +} + +func (u *UserProvider) Service() string { + return "com.ikurento.user.UserProvider" +} + +func (u *UserProvider) Version() string { + return "" +} diff --git a/examples/dubbo/go-server/app/version.go b/examples/dubbo/go-server/app/version.go new file mode 100644 index 0000000000000000000000000000000000000000..c7552b26e11ec15fd51f3e18905d35d577647cd7 --- /dev/null +++ b/examples/dubbo/go-server/app/version.go @@ -0,0 +1,5 @@ +package main + +var ( + Version string = "0.3.1" +) diff --git a/examples/dubbo/go-server/assembly/bin/load.sh b/examples/dubbo/go-server/assembly/bin/load.sh new file mode 100644 index 0000000000000000000000000000000000000000..e202ff65f436f08191ae5364378f659de858777a --- /dev/null +++ b/examples/dubbo/go-server/assembly/bin/load.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : dubbogo app devops script +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-05-13 02:01 +# FILE : load.sh +# ****************************************************** + +APP_NAME="APPLICATION_NAME" +APP_ARGS="" + + +PROJECT_HOME="" +OS_NAME=`uname` +if [[ ${OS_NAME} != "Windows" ]]; then + PROJECT_HOME=`pwd` + PROJECT_HOME=${PROJECT_HOME}"/" +fi + +export APP_CONF_FILE=${PROJECT_HOME}"TARGET_CONF_FILE" +export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE" + +usage() { + echo "Usage: $0 start" + echo " $0 stop" + echo " $0 term" + echo " $0 restart" + echo " $0 list" + echo " $0 monitor" + echo " $0 crontab" + exit +} + +start() { + APP_LOG_PATH="${PROJECT_HOME}logs/" + mkdir -p ${APP_LOG_PATH} + APP_BIN=${PROJECT_HOME}sbin/${APP_NAME} + chmod u+x ${APP_BIN} + # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &" + CMD="${APP_BIN}" + eval ${CMD} + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + CUR=`date +%FT%T` + if [ "${PID}" != "" ]; then + for p in ${PID} + do + echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR} + done + fi +} + +stop() { + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + if [ "${PID}" != "" ]; + then + for ps in ${PID} + do + echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")" + kill -2 ${ps} + done + fi +} + + +term() { + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + if [ "${PID}" != "" ]; + then + for ps in ${PID} + do + echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")" + kill -9 ${ps} + done + fi +} + +list() { + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'` + fi + + if [ "${PID}" != "" ]; then + echo "list ${APP_NAME}" + + if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then + echo "index: user, pid, start, duration" + else + echo "index: PID, WINPID, UID, STIME, COMMAND" + fi + idx=0 + for ps in ${PID} + do + echo "${idx}: ${ps}" + ((idx ++)) + done + fi +} + +opt=$1 +case C"$opt" in + Cstart) + start + ;; + Cstop) + stop + ;; + Cterm) + term + ;; + Crestart) + term + start + ;; + Clist) + list + ;; + C*) + usage + ;; +esac + diff --git a/examples/dubbo/go-server/assembly/common/app.properties b/examples/dubbo/go-server/assembly/common/app.properties new file mode 100644 index 0000000000000000000000000000000000000000..d230d5efc4ee84c4a99e1b27e7b49d97046d91a3 --- /dev/null +++ b/examples/dubbo/go-server/assembly/common/app.properties @@ -0,0 +1,17 @@ +# dubbogo application configure script +# ****************************************************** +# DESC : application environment variable +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:29 +# FILE : app.properties +# ****************************************************** + +TARGET_EXEC_NAME="user_info_server" +# BUILD_PACKAGE="dubbogo-examples/user-info/server/app" +BUILD_PACKAGE="app" + +TARGET_CONF_FILE="conf/server.yml" +TARGET_LOG_CONF_FILE="conf/log.xml" diff --git a/examples/dubbo/go-server/assembly/common/build.sh b/examples/dubbo/go-server/assembly/common/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..a41fbbac321b74849d71b28a65f8b7c5de13cf0f --- /dev/null +++ b/examples/dubbo/go-server/assembly/common/build.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:28 +# FILE : build.sh +# ****************************************************** + +rm -rf target/ + +PROJECT_HOME=`pwd` +TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS} + +TARGET_SBIN_NAME=${TARGET_EXEC_NAME} +version=`cat app/version.go | grep Version | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'` +if [[ ${GOOS} == "windows" ]]; then + TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe +fi +TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME} +if [[ $PROFILE = "test" ]]; then + # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出 + # GFLAGS=-gcflags "-N -l" -race -v + # GFLAGS="-gcflags \"-N -l\" -v" + cd ${BUILD_PACKAGE} && go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd - +else + # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果), + # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试, + # -w基本没啥损失。-s的损失就有点大了。 + cd ${BUILD_PACKAGE} && go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd - +fi + +TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE} + +mkdir -p ${TARGET_FOLDER}/${TAR_NAME} + +SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin +BIN_DIR=${TARGET_FOLDER}/${TAR_NAME} +CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf + +mkdir -p ${SBIN_DIR} +mkdir -p ${CONF_DIR} + +mv ${TARGET_NAME} ${SBIN_DIR} +cp -r assembly/bin ${BIN_DIR} +# modify APPLICATION_NAME +# OS=`uname` +# if [[ $OS=="Darwin" ]]; then +if [ "$(uname)" == "Darwin" ]; then + sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/* +else + sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/* +fi +# modify TARGET_CONF_FILE +if [ "$(uname)" == "Darwin" ]; then + sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/* +else + sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/* +fi +# modify TARGET_LOG_CONF_FILE +if [ "$(uname)" == "Darwin" ]; then + sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/* +else + sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/* +fi + +cp -r profiles/${PROFILE}/* ${CONF_DIR} + +cd ${TARGET_FOLDER} + +tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/* + diff --git a/examples/dubbo/go-server/assembly/linux/dev.sh b/examples/dubbo/go-server/assembly/linux/dev.sh new file mode 100644 index 0000000000000000000000000000000000000000..55886f09fb4873be84cfa46aae592f5f000120a4 --- /dev/null +++ b/examples/dubbo/go-server/assembly/linux/dev.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for dev env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2018-06-24 17:32 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +PROFILE=dev + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/linux/release.sh b/examples/dubbo/go-server/assembly/linux/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..9772ad9614583917d62beba2db9fcaefea63e1ed --- /dev/null +++ b/examples/dubbo/go-server/assembly/linux/release.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +PROFILE=release + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/linux/test.sh b/examples/dubbo/go-server/assembly/linux/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..2fc4a98862bee5ef11a23e1b74058627a899181d --- /dev/null +++ b/examples/dubbo/go-server/assembly/linux/test.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for test env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +PROFILE=test + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/mac/dev.sh b/examples/dubbo/go-server/assembly/mac/dev.sh new file mode 100644 index 0000000000000000000000000000000000000000..5dfa78490b895ce556c809ead32b6f517a5f1450 --- /dev/null +++ b/examples/dubbo/go-server/assembly/mac/dev.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for dev env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2018-06-24 17:32 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=dev + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/mac/release.sh b/examples/dubbo/go-server/assembly/mac/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..1ec21c7b511ccce9eddfac22a2374b57a7a697bf --- /dev/null +++ b/examples/dubbo/go-server/assembly/mac/release.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=release + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/mac/test.sh b/examples/dubbo/go-server/assembly/mac/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..d34914c7dbed0e442b4accf51a3ecdf7c2984db8 --- /dev/null +++ b/examples/dubbo/go-server/assembly/mac/test.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:25 +# FILE : release.sh +# ****************************************************** + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=test + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi + diff --git a/examples/dubbo/go-server/assembly/windows/dev.sh b/examples/dubbo/go-server/assembly/windows/dev.sh new file mode 100644 index 0000000000000000000000000000000000000000..97fbb6f698e500ad08d971b13cc1ffd00cd97803 --- /dev/null +++ b/examples/dubbo/go-server/assembly/windows/dev.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for dev env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2018-06-24 17:34 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +PROFILE=dev + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/windows/release.sh b/examples/dubbo/go-server/assembly/windows/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..782cb10c7828eb277b5905f10f8dd6ad1c2d6bed --- /dev/null +++ b/examples/dubbo/go-server/assembly/windows/release.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +PROFILE=release + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/assembly/windows/test.sh b/examples/dubbo/go-server/assembly/windows/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..2037ddecf2545f1543d5d28be728fb0899722098 --- /dev/null +++ b/examples/dubbo/go-server/assembly/windows/test.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for test env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +PROFILE=test + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then +. ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/go-server/profiles/dev/log.xml b/examples/dubbo/go-server/profiles/dev/log.xml new file mode 100644 index 0000000000000000000000000000000000000000..d2a0d89394aa2b5a882924752d9b7bab7f424dc7 --- /dev/null +++ b/examples/dubbo/go-server/profiles/dev/log.xml @@ -0,0 +1,73 @@ +<logging> + <filter enabled="true"> + <tag>stdout</tag> + <type>console</type> + <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) --> + <level>DEBUG</level> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] (%S) %M</property> <!-- log format, if json is false this option is enable --> + </filter> + <filter enabled="true"> + <tag>debug_file</tag> + <type>file</type> + <level>DEBUG</level> + <property name="filename">logs/debug.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>info_file</tag> + <type>file</type> + <level>INFO</level> + <property name="filename">logs/info.log</property> + <!-- + %T - Time (15:04:05 MST) + %t - Time (15:04) + %D - Date (2006/01/02) + %d - Date (01/02/06) + %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT) + %S - Source + %M - Message + It ignores unknown format strings (and removes them) + Recommended: "[%D %T] [%L] (%S) %M" + --> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>warn_file</tag> + <type>file</type> + <level>WARNING</level> + <property name="filename">logs/warn.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>error_file</tag> + <type>file</type> + <level>ERROR</level> + <property name="filename">logs/error.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> +</logging> diff --git a/examples/dubbo/go-server/profiles/dev/server.yml b/examples/dubbo/go-server/profiles/dev/server.yml new file mode 100644 index 0000000000000000000000000000000000000000..421f0b57634d8dd645be6dd4f02f409035b53af2 --- /dev/null +++ b/examples/dubbo/go-server/profiles/dev/server.yml @@ -0,0 +1,39 @@ +# dubbo server yaml configure file + +# pprof +pprof_enabled : true +pprof_port : 20080 + +# server +transport : "http" +net_timeout : "3s" + +# application config +application_config: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "dev" + +registry: "zookeeper" + +zk_registry_config: + timeout : "3s" + address: + - "127.0.0.1:2181" + +service_list: + - + protocol : "dubbo" + # 相当于dubbo.xml中的interface + service : "com.ikurento.user.UserProvider" + +server_list: + - + # 如果是127.0.0.1, java-client将无法连接到go-server + ip : "192.168.56.1" + port : 20000 + # 本server能够提供所有支持同样的Protocol的servicelist的服务 + protocol : "dubbo" diff --git a/examples/dubbo/go-server/profiles/release/log.xml b/examples/dubbo/go-server/profiles/release/log.xml new file mode 100644 index 0000000000000000000000000000000000000000..834bab5b07e72f1c250d500b60fe3af25e74cfc1 --- /dev/null +++ b/examples/dubbo/go-server/profiles/release/log.xml @@ -0,0 +1,73 @@ +<logging> + <filter enabled="false"> + <tag>stdout</tag> + <type>console</type> + <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) --> + <level>DEBUG</level> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] (%S) %M</property> <!-- log format, if json is false this option is enable --> + </filter> + <filter enabled="false"> + <tag>debug_file</tag> + <type>file</type> + <level>DEBUG</level> + <property name="filename">logs/debug.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="false"> + <tag>info_file</tag> + <type>file</type> + <level>INFO</level> + <property name="filename">logs/info.log</property> + <!-- + %T - Time (15:04:05 MST) + %t - Time (15:04) + %D - Date (2006/01/02) + %d - Date (01/02/06) + %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT) + %S - Source + %M - Message + It ignores unknown format strings (and removes them) + Recommended: "[%D %T] [%L] (%S) %M" + --> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>warn_file</tag> + <type>file</type> + <level>WARNING</level> + <property name="filename">logs/warn.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>error_file</tag> + <type>file</type> + <level>ERROR</level> + <property name="filename">logs/error.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> +</logging> diff --git a/examples/dubbo/go-server/profiles/release/server.yml b/examples/dubbo/go-server/profiles/release/server.yml new file mode 100644 index 0000000000000000000000000000000000000000..d8b341d273cef38101ce375ca16e0f99362c191b --- /dev/null +++ b/examples/dubbo/go-server/profiles/release/server.yml @@ -0,0 +1,38 @@ +# dubbo server yaml configure file + +# pprof +pprof_enabled : true +pprof_port : 20080 + +# server +transport : "http" +net_timeout : "3s" + +# application config +application_config: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "product" + +registry: "zookeeper" + +zk_registry_config: + timeout : "3s" + address: + - "127.0.0.1:2181" + +service_list: + - + protocol : "dubbo" + # 相当于dubbo.xml中的interface + service : "com.ikurento.user.UserProvider" + +server_list: + - + ip : "127.0.0.1" + port : 20000 + # 本server能够提供所有支持同样的Protocol的servicelist的服务 + protocol : "dubbo" diff --git a/examples/dubbo/go-server/profiles/test/log.xml b/examples/dubbo/go-server/profiles/test/log.xml new file mode 100644 index 0000000000000000000000000000000000000000..834bab5b07e72f1c250d500b60fe3af25e74cfc1 --- /dev/null +++ b/examples/dubbo/go-server/profiles/test/log.xml @@ -0,0 +1,73 @@ +<logging> + <filter enabled="false"> + <tag>stdout</tag> + <type>console</type> + <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) --> + <level>DEBUG</level> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] (%S) %M</property> <!-- log format, if json is false this option is enable --> + </filter> + <filter enabled="false"> + <tag>debug_file</tag> + <type>file</type> + <level>DEBUG</level> + <property name="filename">logs/debug.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="false"> + <tag>info_file</tag> + <type>file</type> + <level>INFO</level> + <property name="filename">logs/info.log</property> + <!-- + %T - Time (15:04:05 MST) + %t - Time (15:04) + %D - Date (2006/01/02) + %d - Date (01/02/06) + %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT) + %S - Source + %M - Message + It ignores unknown format strings (and removes them) + Recommended: "[%D %T] [%L] (%S) %M" + --> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>warn_file</tag> + <type>file</type> + <level>WARNING</level> + <property name="filename">logs/warn.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> + <filter enabled="true"> + <tag>error_file</tag> + <type>file</type> + <level>ERROR</level> + <property name="filename">logs/error.log</property> + <property name="json">false</property> <!-- true enables json log format, its priority is high than format --> + <property name="format">[%D %T] [%L] [%S] %M</property> + <property name="rotate">true</property> <!-- true enables log rotation, otherwise append --> + <property name="maxsize">0M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 --> + <property name="maxlines">0K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands --> + <property name="maxbackup">16</property> <!-- \d+ --> + <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight --> + </filter> +</logging> diff --git a/examples/dubbo/go-server/profiles/test/server.yml b/examples/dubbo/go-server/profiles/test/server.yml new file mode 100644 index 0000000000000000000000000000000000000000..6b786929866f2e96f6ca81a8c9a63c319d2a3f99 --- /dev/null +++ b/examples/dubbo/go-server/profiles/test/server.yml @@ -0,0 +1,38 @@ +# dubbo server yaml configure file + +# pprof +pprof_enabled : true +pprof_port : 20080 + +# server +transport : "http" +net_timeout : "3s" + +# application config +application_config: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "test" + +registry: "zookeeper" + +zk_registry_config: + timeout : "3s" + address: + - "127.0.0.1:2181" + +service_list: + - + protocol : "dubbo" + # 相当于dubbo.xml中的interface + service : "com.ikurento.user.UserProvider" + +server_list: + - + ip : "127.0.0.1" + port : 20000 + # 本server能够提供所有支持同样的Protocol的servicelist的服务 + protocol : "dubbo" 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 a72f3b7e96a7f0f687da90f763fc63a148e5bc1c..727007257fc5bb1e4d1aa73cfca8aa804a766e93 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 @@ -34,7 +34,7 @@ <!-- 声明需要使用的服务接口 --> <!--<dubbo:reference id="userProvider" protocol="jsonrpc" interface="com.ikurento.user.UserProvider">--> - <dubbo:reference id="userProvider" protocol="dubbo" 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> diff --git a/examples/dubbo/java-client/src/main/resources/dubbo.properties b/examples/dubbo/java-client/src/main/resources/dubbo.properties deleted file mode 100644 index e561efcf8f9fdb886191bfba775bfd0b62eaeba2..0000000000000000000000000000000000000000 --- a/examples/dubbo/java-client/src/main/resources/dubbo.properties +++ /dev/null @@ -1,13 +0,0 @@ -### dubboע���������� ### -dubbo.container = log4j,spring -dubbo.application.name = user-info-client -dubbo.application.owner = AlexStocks -dubbo.application.environment = product -dubbo.registry.address = zookeeper://127.0.0.1:2181 -dubbo.monitor.protocol = zookeeper -dubbo.consumer.timeout = 10000 -dubbo.provider.timeout = 10000 -dubbo.protocol.name = dubbo - -dubbo.log4j.file = logs/client.log -dubbo.log4j.level = WARN diff --git a/examples/jsonrpc/go-client/app/test.go b/examples/jsonrpc/go-client/app/test.go index cb9ea0220ddd8d9079e4121613a5b8d91271ae39..b46da6eb2ac35f947da56690ce195c6c43ea7f3c 100644 --- a/examples/jsonrpc/go-client/app/test.go +++ b/examples/jsonrpc/go-client/app/test.go @@ -11,9 +11,9 @@ import ( ) import ( + "github.com/dubbo/dubbo-go/client" "github.com/dubbo/dubbo-go/examples" "github.com/dubbo/dubbo-go/public" - "github.com/dubbo/dubbo-go/client" "github.com/dubbo/dubbo-go/registry" ) diff --git a/go.mod b/go.mod index cc0b851ac316898b31339c41c6f9dc2bad8c3c5d..104d9e2ce098e1c165a3791a0b1add6c8ddc266e 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,12 @@ module github.com/dubbo/dubbo-go require ( - github.com/AlexStocks/getty v1.0.4 + github.com/AlexStocks/getty v0.0.0-20190331201845-1ca64ac5a589 github.com/AlexStocks/goext v0.3.2 github.com/AlexStocks/log4go v1.0.2 github.com/dubbogo/hessian2 v0.0.0-20190331022028-ade83b794bf2 github.com/juju/errors v0.0.0-20190207033735-e65537c515d7 + github.com/pkg/errors v0.8.1 github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index 789f294efdcab00539c5fdf5bb336a112d1341d6..42757d365ac49aa3bcab42a9e743fda8acdbf2f3 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/AlexStocks/getty v1.0.4 h1:SGv/6104d1GHAi5cm24Q50H9jsXZzEnNX1cmRno7N8s= -github.com/AlexStocks/getty v1.0.4/go.mod h1:n25mdqPgFi06sWL6mZTjm1hBIZuKwgXUVXAX+KGB97U= +github.com/AlexStocks/getty v0.0.0-20190331201845-1ca64ac5a589 h1:iat4jfMomN+G0SqwLJRUM2iha0LHwX+VpdT8PR8NihA= +github.com/AlexStocks/getty v0.0.0-20190331201845-1ca64ac5a589/go.mod h1:n25mdqPgFi06sWL6mZTjm1hBIZuKwgXUVXAX+KGB97U= github.com/AlexStocks/goext v0.3.2 h1:Bn4C+R6/E5Yjk2Uc/voawtbGv91x9aCid92xwYL2AS0= github.com/AlexStocks/goext v0.3.2 h1:Bn4C+R6/E5Yjk2Uc/voawtbGv91x9aCid92xwYL2AS0= github.com/AlexStocks/goext v0.3.2/go.mod h1:3M5j9Pjge4CdkNg2WIjRLUeoPedJHHKwkkglDGSl3Hc= @@ -80,6 +80,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd h1:22rhYEzttbrnKjgYh5pifnDluXHHcJ3uSOi2l8Nw+9A= github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd/go.mod h1:JrOIxq3vDxvtuEI7Kmm2yqkuBfuT9DMLFMnCyYHLaKM= github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd/go.mod h1:JrOIxq3vDxvtuEI7Kmm2yqkuBfuT9DMLFMnCyYHLaKM= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/jsonrpc/http.go b/jsonrpc/http.go index 346be011f66922709798632a9acde255540ba6a7..fe383c0c6e3023a72a0df806b5f903400a538730 100644 --- a/jsonrpc/http.go +++ b/jsonrpc/http.go @@ -20,9 +20,9 @@ import ( ) import ( + "github.com/dubbo/dubbo-go/client" "github.com/dubbo/dubbo-go/public" "github.com/dubbo/dubbo-go/registry" - "github.com/dubbo/dubbo-go/client" ) ////////////////////////////////////////////// diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 62d64c3cbc36f060ca106178ba09b2dd34aeabc6..32872f633fc419d0c1c1af25a0ed30be415c6648 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -239,7 +239,6 @@ LOOP: } } - func (r *ZkRegistry) Register(regConf registry.ServiceConfig) error { var ( ok bool @@ -307,8 +306,6 @@ func (r *ZkRegistry) Register(regConf registry.ServiceConfig) error { log.Debug("(ZkProviderRegistry)Register(conf{%#v})", conf) } - - return nil }