优化gateway-减少GC

This commit is contained in:
boyce
2020-11-03 14:53:49 +08:00
parent 060095baea
commit 974fbd3584
12 changed files with 155 additions and 119 deletions

View File

@@ -175,7 +175,6 @@ func (client *Client) AsyncCall(rpcHandler IRpcHandler,serviceMethod string,call
}
request := &RpcRequest{}
call.Arg = args
call.Seq = client.generateSeq()
request.RpcRequestData = processor.MakeRpcRequest(client.startSeq,serviceMethod,false,InParam,nil)
client.AddPending(call)
@@ -209,7 +208,6 @@ func (client *Client) RawGo(processor IRpcProcessor,noReply bool,serviceMethod s
call.Reply = reply
request := &RpcRequest{}
call.Arg = args
call.Seq = client.generateSeq()
if noReply == false {
client.AddPending(call)

View File

@@ -61,26 +61,26 @@ func (slf *PBRpcRequestData) MakeRequest(seq uint64,serviceMethod string,noReply
}
switch inAdditionParam.(type) {
case *int:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{int64(*inAdditionParam.(*int))}}
case *int32:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{int64(*inAdditionParam.(*int32))}}
case *int16:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{int64(*inAdditionParam.(*int16))}}
case *int64:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{*inAdditionParam.(*int64)}}
case *uint:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{uint64(*inAdditionParam.(*uint))}}
case *uint32:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{uint64(*inAdditionParam.(*uint32))}}
case *uint16:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{uint64(*inAdditionParam.(*uint16))}}
case *uint64:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{*inAdditionParam.(*uint64)}}
case *string:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_StrParam{*inAdditionParam.(*string)}}
case *[]byte:
slf.AddtionParam = &AdditionParam{AdditionOneof: &AdditionParam_BParam{*inAdditionParam.(*[]byte)}}
case int:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{int64(inAdditionParam.(int))}}
case int32:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{int64(inAdditionParam.(int32))}}
case int16:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{int64(inAdditionParam.(int16))}}
case int64:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_SParam{inAdditionParam.(int64)}}
case uint:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{uint64(inAdditionParam.(uint))}}
case uint32:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{uint64(inAdditionParam.(uint32))}}
case uint16:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{uint64(inAdditionParam.(uint16))}}
case uint64:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_UParam{inAdditionParam.(uint64)}}
case string:
slf.AddtionParam = &AdditionParam{AdditionOneof:&AdditionParam_StrParam{inAdditionParam.(string)}}
case []byte:
slf.AddtionParam = &AdditionParam{AdditionOneof: &AdditionParam_BParam{inAdditionParam.([]byte)}}
default:
panic(fmt.Sprintf("not support type %+v",inAdditionParam))
}

View File

@@ -12,7 +12,8 @@ type RpcRequest struct {
bLocalRequest bool
localReply interface{}
localParam interface{} //本地调用的参数列表
localRawParam []byte
inputArgs IRawInputArgs
requestHandle RequestHandler
callback *reflect.Value
rpcProcessor IRpcProcessor
@@ -44,6 +45,12 @@ type IRpcResponseData interface {
GetReply() []byte
}
type IRawInputArgs interface {
GetRawData() []byte //获取原始数据
GetAdditionParam() interface{} //获取附加数据
DoGc() //处理完成,回收内存
}
type RpcHandleFinder interface {
FindRpcHandler(serviceMethod string) IRpcHandler
}
@@ -55,7 +62,6 @@ type RawAdditionParamNull struct {
type Call struct {
Seq uint64
ServiceMethod string
Arg interface{}
Reply interface{}
Response *RpcResponse
Err error
@@ -93,7 +99,6 @@ func (rpcResponse *RpcResponse) Clear() *RpcResponse{
func (call *Call) Clear() *Call{
call.Seq = 0
call.ServiceMethod = ""
call.Arg = nil
call.Reply = nil
call.Response = nil
call.Err = nil

View File

@@ -77,8 +77,7 @@ type IRpcHandler interface {
AsyncCallNode(nodeId int,serviceMethod string,args interface{},callback interface{}) error
CallNode(nodeId int,serviceMethod string,args interface{},reply interface{}) error
GoNode(nodeId int,serviceMethod string,args interface{}) error
RawGoNode(rpcProcessorType RpcProcessorType,nodeId int,serviceMethod string,args []byte,additionParam interface{}) error
RawCastGo(rpcProcessorType RpcProcessorType,serviceMethod string,args []byte,additionParam interface{})
RawGoNode(rpcProcessorType RpcProcessorType,nodeId int,serviceMethod string,args IRawInputArgs) error
IsSingleCoroutine() bool
}
@@ -230,6 +229,9 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
}()
defer ReleaseRpcRequest(request)
defer request.rpcProcessor.ReleaseRpcRequest(request.RpcRequestData)
if request.inputArgs!=nil {
defer request.inputArgs.DoGc()
}
v,ok := handler.mapFunctions[request.RpcRequestData.GetServiceMethod()]
if ok == false {
@@ -262,8 +264,8 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
return
}
}else {
if request.localRawParam!=nil {
err = request.rpcProcessor.Unmarshal(request.localRawParam,iParam)
if request.inputArgs!=nil {
err = request.rpcProcessor.Unmarshal(request.inputArgs.GetRawData(),iParam)
if err!=nil {
rErr := Errorf("Call Rpc %s Param error %+v",request.RpcRequestData.GetServiceMethod(),err)
log.Error("%s", rErr.Error())
@@ -373,7 +375,7 @@ func (handler *RpcHandler) goRpc(processor IRpcProcessor,bCast bool,nodeId int,s
return pLocalRpcServer.myselfRpcHandlerGo(sMethod[0],sMethod[1],args,nil)
}
//其他的rpcHandler的处理器
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(processor,pClient,true,sMethod[0],sMethod[1],args,nil,nil,nil)
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(processor,pClient,true,sMethod[0],sMethod[1],args,nil,nil)
if pCall.Err!=nil {
err = pCall.Err
}
@@ -392,59 +394,6 @@ func (handler *RpcHandler) goRpc(processor IRpcProcessor,bCast bool,nodeId int,s
return err
}
func (handler *RpcHandler) rawGoRpc(processor IRpcProcessor,bCast bool,nodeId int,serviceMethod string,args []byte,additionParam interface{}) error {
var pClientList []*Client
err := handler.funcRpcClient(nodeId,serviceMethod,&pClientList)
if err != nil {
log.Error("Call serviceMethod is error:%+v!",err)
return err
}
if len(pClientList) > 1 && bCast == false {
log.Error("Cannot call more then 1 node!")
return fmt.Errorf("Cannot call more then 1 node!")
}
//2.rpcclient调用
//如果调用本结点服务
for _,pClient := range pClientList {
if pClient.bSelfNode == true {
pLocalRpcServer:= handler.funcRpcServer()
//判断是否是同一服务
sMethod := strings.Split(serviceMethod,".")
if len(sMethod)!=2 {
serr := fmt.Errorf("Call serviceMethod %s is error!",serviceMethod)
log.Error("%+v",serr)
if serr!= nil {
err = serr
}
continue
}
//调用自己rpcHandler处理器
if sMethod[0] == handler.rpcHandler.GetName() { //自己服务调用
//
return pLocalRpcServer.myselfRpcHandlerGo(sMethod[0],sMethod[1],args,nil)
}
//其他的rpcHandler的处理器
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(processor,pClient,true,sMethod[0],sMethod[1],nil,args,nil,additionParam)
if pCall.Err!=nil {
err = pCall.Err
}
ReleaseCall(pCall)
continue
}
//跨node调用
pCall := pClient.RawGo(processor,true,serviceMethod,args,additionParam,nil)
if pCall.Err!=nil {
err = pCall.Err
}
ReleaseCall(pCall)
}
return err
}
func (handler *RpcHandler) callRpc(nodeId int,serviceMethod string,args interface{},reply interface{}) error {
var pClientList []*Client
err := handler.funcRpcClient(nodeId,serviceMethod,&pClientList)
@@ -475,7 +424,7 @@ func (handler *RpcHandler) callRpc(nodeId int,serviceMethod string,args interfac
return pLocalRpcServer.myselfRpcHandlerGo(sMethod[0],sMethod[1],args,reply)
}
//其他的rpcHandler的处理器
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(nil,pClient,false,sMethod[0],sMethod[1],args,nil,reply,nil)
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(nil,pClient,false,sMethod[0],sMethod[1],args,reply,nil)
err = pCall.Done().Err
pClient.RemovePending(pCall.Seq)
ReleaseCall(pCall)
@@ -560,7 +509,7 @@ func (handler *RpcHandler) asyncCallRpc(nodeid int,serviceMethod string,args int
}
return nil
}
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(nil,pClient,false,sMethod[0],sMethod[1],args,nil,reply,nil)
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(nil,pClient,false,sMethod[0],sMethod[1],args,reply,nil)
err = pCall.Done().Err
pClient.RemovePending(pCall.Seq)
ReleaseCall(pCall)
@@ -612,11 +561,61 @@ func (handler *RpcHandler) CastGo(serviceMethod string,args interface{}) {
handler.goRpc(nil,true,0,serviceMethod,args)
}
func (handler *RpcHandler) RawGoNode(rpcProcessorType RpcProcessorType,nodeId int,serviceMethod string,args []byte,additionParam interface{}) error {
return handler.rawGoRpc(GetProcessor(uint8(rpcProcessorType)),false,nodeId,serviceMethod,args,additionParam)
}
func (handler *RpcHandler) RawCastGo(rpcProcessorType RpcProcessorType,serviceMethod string,args []byte,additionParam interface{}) {
handler.goRpc(GetProcessor(uint8(rpcProcessorType)),true,0,serviceMethod,args)
func (handler *RpcHandler) RawGoNode(rpcProcessorType RpcProcessorType,nodeId int,serviceMethod string,args IRawInputArgs) error {
processor := GetProcessor(uint8(rpcProcessorType))
var pClientList []*Client
err := handler.funcRpcClient(nodeId,serviceMethod,&pClientList)
if err != nil {
args.DoGc()
log.Error("Call serviceMethod is error:%+v!",err)
return err
}
if len(pClientList) > 1 {
args.DoGc()
log.Error("Cannot call more then 1 node!")
return fmt.Errorf("Cannot call more then 1 node!")
}
//2.rpcclient调用
//如果调用本结点服务
for _,pClient := range pClientList {
if pClient.bSelfNode == true {
pLocalRpcServer:= handler.funcRpcServer()
//判断是否是同一服务
sMethod := strings.Split(serviceMethod,".")
if len(sMethod)!=2 {
serr := fmt.Errorf("Call serviceMethod %s is error!",serviceMethod)
log.Error("%+v",serr)
if serr!= nil {
err = serr
}
continue
}
//调用自己rpcHandler处理器
if sMethod[0] == handler.rpcHandler.GetName() { //自己服务调用
err:= pLocalRpcServer.myselfRpcHandlerGo(sMethod[0],sMethod[1],args,nil)
args.DoGc()
return err
}
//其他的rpcHandler的处理器
pCall := pLocalRpcServer.selfNodeRpcHandlerGo(processor,pClient,true,sMethod[0],sMethod[1],nil,nil,args)
if pCall.Err!=nil {
err = pCall.Err
}
ReleaseCall(pCall)
continue
}
//跨node调用
pCall := pClient.RawGo(processor,true,serviceMethod,args.GetRawData(),args.GetAdditionParam(),nil)
args.DoGc()
if pCall.Err!=nil {
err = pCall.Err
}
ReleaseCall(pCall)
}
return err
}

View File

@@ -214,8 +214,8 @@ func (agent *RpcAgent) Destroy() {
agent.conn.Destroy()
}
func (server *Server) NewAgent(conn *network.TCPConn) network.Agent {
agent := &RpcAgent{conn: conn, rpcServer: server}
func (server *Server) NewAgent(c *network.TCPConn) network.Agent {
agent := &RpcAgent{conn: c, rpcServer: server}
return agent
}
@@ -232,12 +232,15 @@ func (server *Server) myselfRpcHandlerGo(handlerName string,methodName string, a
}
func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor,client *Client,noReply bool,handlerName string,methodName string, args interface{},rawArgs []byte,reply interface{},additionParam interface{}) *Call {
func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor,client *Client,noReply bool,handlerName string,methodName string, args interface{},reply interface{},inputArgs IRawInputArgs) *Call {
pCall := MakeCall()
pCall.Seq = client.generateSeq()
rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName)
if rpcHandler== nil {
if inputArgs!= nil {
inputArgs.DoGc()
}
pCall.Err = fmt.Errorf("service method %s.%s not config!", handlerName,methodName)
log.Error("%s",pCall.Err.Error())
pCall.done <- pCall
@@ -248,11 +251,14 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor,client *Clien
req.bLocalRequest = true
req.localParam = args
req.localReply = reply
req.localRawParam = rawArgs
req.inputArgs = inputArgs
if processor == nil {
_,processor = GetProcessorType(args)
}
var additionParam interface{}
if inputArgs!=nil {
additionParam = inputArgs.GetAdditionParam()
}
req.RpcRequestData = processor.MakeRpcRequest(0,fmt.Sprintf("%s.%s",handlerName,methodName),noReply,nil,additionParam)
req.rpcProcessor = processor
if noReply == false {