php调用go微服务,go微服务框架go-micro深度学习(四) rpc方法调用过程详解

上一篇帖子

go-micro 支持很多通信协议:http、tcp、grpc等,支持的编码方式也很多有json、protobuf、bytes、jsonrpc等。也可以根据自己的需要实现通信协议和编码方式。go-micro 默认的通信协议是http,默认的编码方式是protobuf,我就以默认的方式来分解他的具体实现。

00387cb66182294b157ade1d9d936fb9.png

服务的启动

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得到的保存信息

4d11e2e7c5a8e33294699261b05dd033.png

路由信息处理完后,主要的工作就已经完成了,然后注册服务并启动服务,启动的服务是一个http的服务,我们可以看一下http_transport.go里的代码

66d751fbe4e430e477a19f9774ebf374.png

服务的简单流程图如下 ,选择通信协议和编码方式->注册服务方法->启动服务并注册服务信息

210382f66f556f1440ab89b9d756ac19.png

客户端调用服务方法

客户端在启动的时候也要选择默认的通信协议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语言编程网!

相关文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值