gRPC 服务端和客户端源码分析(golang)

第一部分 gRPC介绍

gRPC是什么,A high-performance, open-source universal RPC framework。RPC是什么,remote procedure call,远程过程调用,应用程序之间使用RPC通信,函数调用与本地调用无异。
gRPC提供一套server/client模型通信机制,其特点如下:

  • 使用http2.0作为底层传输协议,支持流式通信,多路复用( 多路复用原理:http1.1基于“文本分割”,服务端读取直至遇到分隔符,一次只能处理一个请求或响应,且数据解析无法预知内存大小。http2.0基于二进制“帧”,定义不同类型帧,请求和响应交错复用。流式通信原理:http2.0连接上独立的、双向的帧序列交流。帧首部6-9字节表流ID,用来标识帧所属的流 );
  • 可使用protobuf定义接口数据,二进制编码,减少需要传输的数据量( protobuf轻量:与json比较,json为key-value,每个key都占用多个字节,int类型固定字节数。protobuf使用tag,编号标记key,仅占一字节,支持Varint,数据按实际长度存储)
  • 解决不同语言间通信的复杂性以及环境的不同
  • 一次性在一个.proto文件中定义服务,并使用任何支持它的语言去实现客户端和服务器

gRPC的使用场景与restful API相同。

第二部分 gRPC通信过程源码分析

gRPC提供一套server/client端通信机制,源码分析立足于分析利用gRPC进行模块调用整个通信过程。结合golang grpc使用样例文章中的代码,梳理gRPC通信过程源码。此部分共分为三个小节,分别是:

  • 客户端及服务端入口代码解析
  • 客户端请求逻辑
  • 服务端处理逻辑

1:Server端及Client端入口代码解析
客户端、服务端代码逻辑
如果项目中,你只需要简单的利用gRPC远程调用函数。由上图可知,用户只需关心一下几点:
服务端:

  • 注册并开启服务
  • 持续监听client请求

客户端:

  • 与server端建立连接
  • 初始化客户端并构建msg
  • 请求服务端,并接收响应数据

其中,客户端请求c.SayHello()指定调用 "/proto.Hello/SayHello"服务端定义的helloService.SayHello()。由helloService.SayHello()的执行逻辑可知,其将client端请求的“hello world!”消息直接返回client端。
那么,client端的request是如何发送值server端,server端接收消息,调用helloService.SayHello()函数后,是如何将消息返回client端的,是接下来我们具体研究的内容。

2、客户端请求逻辑
client调用grpc.Dial(),返回一个ClientConn,底层本质上调用newHTTP2Client,与server建立http2连接。

func newHTTP2Client(), onClose func()) (_ *http2Client, err error) {
   
    //dial一个tcp连接
	conn, err := dial(connectCtx, opts.Dialer, addr.Addr)
    
    //循环读取帧,并按类型分发入流
	go t.reader()
	// Send connection preface to server.
	n, err := t.conn.Write(clientPreface)
	/*************省略***********/
}

调用grpc.Dial()之后,client和server的连接已经建立起来了,此时需初始化客户端对象:

c := pb.NewHelloClient(conn)//创建helloClient实例

func NewHelloClient(cc grpc.ClientConnInterface) HelloClient {
   
	return &helloClient{
   cc}
}

初始化的helloClient向server发起一次请求msg,即调用hello.pb.go文件中的helloClient.SayHello()方法,其最终还是调用grpc.Invoke()。

	r, err := c.SayHello(context.Background(), reqBody)//调用helloClient对象的的SayHello()方法,并传入参数

func (c *helloClient) SayHello(ctx context.Context, in *Request, opts ...grpc.CallOption) 
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值