上一篇帖子
go-micro 支持很多通信协议:http、tcp、grpc等,支持的编码方式也很多有json、protobuf、bytes、jsonrpc等。也可以根据自己的需要实现通信协议和编码方式。go-micro 默认的通信协议是http,默认的编码方式是protobuf,我就以默认的方式来分解他的具体实现。
服务的启动
go-micro在启动的时候会选择默认通信协议http和protobuf编码方式,但他是如何路由到具体方法的?在go-micro服务端启动的时候我们需要注册Handler,也就是我们具体实现结构体 ,如例子中注册方法时,我们调用的RegisterSayHandler方法
//注册 Handler
rpcapi.RegisterSayHandler(service.Server(), new(handler.Say))
这个方法内部的体实现主要是利用了反射的力量,注册的对象是实现了rpc接口的方法,如我们的Say实现了SayHandler。go-micro默认的router会利用反射把Say对象的信息完全提取出来,解析出结构体内的方法及方法的参数,保存到一个map内-> map[结构体名称][方法信息集合]
具体的实现在rpc_router.go里router的Handle(Handler)方法,组织完成后map的是下图这样,保存了很多反射信息,用以将来调用。
下面是这个方法的主要代码,删除了一些,很希望大家读一下rpc_router.go里面的代码,prepareMethod方法是具体利用反射提取信息的方法。
func (router *router) Handle(h Handler) error {
router.mu.Lock()
defer router.mu.Unlock()//....
rcvr :=h.Handler()
s := new(service)
s.typ=reflect.TypeOf(rcvr)
s.rcvr=reflect.ValueOf(rcvr)//check name//....
s.name =h.Name()
s.method= make(map[string]*methodType)//Install the methods
for m := 0; m < s.typ.NumMethod(); m++{
method :=s.typ.Method(m)//prepareMethod会把所有解析的信息返回来
if mt := prepareMethod(method); mt !=nil {
s.method[method.Name]=mt
}
}//.....//save handler
router.serviceMap[s.name] =sreturnnil
}
serviceMap里保存的就是反射后的信息,下图是我用goland的debug得到的保存信息
路由信息处理完后,主要的工作就已经完成了,然后注册服务并启动服务,启动的服务是一个http的服务,我们可以看一下http_transport.go里的代码
服务的简单流程图如下 ,选择通信协议和编码方式->注册服务方法->启动服务并注册服务信息
客户端调用服务方法
客户端在启动的时候也要选择默认的通信协议http,和protobuf编码。客户端在调用rpc方法的时候如:
rsp, err := client.Hello(context.Background(), &model.SayParam{Msg: "hello server"})
go-micro为我们自动生成的rpcapi.micro.go里我们可以看一上Hello的具体实现,没有几行代码,但内部还是做了很多工作
func (c *sayService) Hello(ctx context.Context, in *model.SayParam, opts ...client.CallOption) (*model.SayResponse, error) {
req := c.c.NewRequest(c.name, "Say.Hello", in)out := new(model.SayResponse)
err := c.c.Call(ctx, req, out, opts...)if err !=nil {returnnil, err
}return out, nil
}
作者: li-peng
链接: http://www.cnblogs.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
到此这篇关于“go微服务框架go-micro深度学习(四) rpc方法调用过程详解”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持Go语言编程网!
相关文章: