grpc客户端连接源码解读

最近在做grpc连接池的优化,正巧之前只是粗略地读了一些grpc的源码,借这个机会把相关grpc的源码认真读一读,更深入地理解grpc客户端连接的参数,帮助优化grpc连接池。

图解grpc客户端连接

后面的内容都是大段地贴代码,并且因为时间原因没有写得非常细致,只是罗列了大概的脉络。所以先贴一张图出来,方便对grpc client connection的层次结构建立整体的认知,无论是看接下来我贴的代码还是自己去读源码都会非常有帮助。
在这里插入图片描述

从Dial方法开始

在grpc client一侧,通常上来要先通过grpc.Dial或者grcp.DialContext方法创建客户端的连接(dial其实也是调用了dialContext)。那我们也先从DialContext方法开始,看下其做了哪些事情。

DialContext的签名为传入target以及options,然后得到clientConn对象,其中target表示server端的地址,options用来传递一些参数。所以DialContext方法开始就初始化了ClientConn对象,并将options参数应用到ClientConn的dopts(dial options)字段中,随后将注册的拦截器做了初始化操作。


接下来仍然是一些初始化的操作。channelz是可以提供grpc的运行时的信息,是属于可观测性工具,并不涉及具体的功能,所以看代码时可以略过这部分。首先是grpc加密安全相关的参数,其transportCredentials为接口类型,实现了ClientHandshake和ServerHandshake方法,可以在net.Conn上实现封装。接下来是service config相关,service config有两种方式传入,一是通过json的形式在初始化时传入,另外是通过传入chan *ServiceConfig,clientConn动态监听chan并且将变动应用。


再然后对传入的target进行解析,根据target解析结果的schema拿到resolverBuilder。这里的schema主要指带不同的协议,grpc支持dns、unix、tcp等协议,resolver的作用就是将相应的endpoint解析为具体的address。304行生成了balancer的参数。314行根据上面拿到的resolverBuilder生成resolver。如果创建连接时传入了grpc.WithBlock(),则在323行时会在循环里检查ClientConn的状态,只到连接成功或者建连出错或者超时;如果没有选择withBlock,则立即返回,此时的连接处于异步建连状态,不保证建连成功。

一次客户端调用

以unary的调用为例,说明grpc调用中客户端一侧的行为。

调用链路为ClientConn.Invoke -> invoke -> newClientStream,然后分别调用clientStream.SendMsg和clientStream.RecvMsg方法,在底层的stream的异步行为之上构建同步的调用。


接下来,看下newClientStream做了什么事。184行,实际是调用newClientStreamWithParams。

newClientStreamWithParams这个方法比较长,我们只列出一些主干的部分。首先是参数准备。

实例化clientStream对象并调用newAttemptLocked方法初始化attempt对象。

333行代码封装了op方法,在334行中withRetry调用,其实就是调用attempt的newStream方法。

attempt对象里真正地持有了transport,也就是底层的连接。

上面说了attemp持有底层的transport对象,newStream就是在transport的基础上创建stream。

在http2连接上创建stream。

调用clientStream的SendMsg方法,调用链路为clientStream.SendMsg - > csAttempt.sendMsg -> http2Client.Write -> controlBuffer.Pu。放到controlBuffer之后loopWriter协程异步地写到framer中,framer其实就是在底层连接上包了一层的buffer。


客户端连接

异步连接。 看下http2的连接是如何创建的。 dial方法创建传输层的连接,如果创建clientConnection时传入dialer则使用该方法,否则则使用默认方法。 实例化http2Client对象。 创建controlBuffer。 异步起reader和writer协程。

如果觉得本文对您有帮助,可以请博主喝杯咖啡~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值