【gRPC】4—gRPC与Netty

gRPC与Netty

⭐⭐⭐⭐⭐⭐
Github主页👉https://github.com/A-BigTree
笔记链接👉https://github.com/A-BigTree/Code_Learning
⭐⭐⭐⭐⭐⭐

如果可以,麻烦各位看官顺手点个star~😊

📖RPC专栏:https://blog.csdn.net/weixin_53580595/category_12368218.html


gRPC跟Netty的关系主要包括如下几方面的依赖:

  1. 依赖Netty实现的HTTP/2协议的封装,通过Listener机制监听HTTP/2的数据报文事件,完成网络相关处理;
  2. Reactor IO模型的依赖,Nio/Epoll;
  3. 依赖Netty的ByteBuf完成流数据在内部中的缓存与流转;

1 几种常见的RPC IO模型

1.1 BIO模型

在这里插入图片描述

主要特点

  1. 每个请求一个IO线程处理
  2. Client消息请求与应答由IO线程完成
  3. IO线程在没有处理完之前会同步阻塞

优点

  1. 想啥呢? 没啥优点

缺点

  1. 吞吐低:每个请求一个线程很容易导致server端出现资源瓶颈从而影响吞吐,频繁创建线程也不能合理利用线程资源(可以通过使用线程池来解决)
  2. 稳定性:由于是阻塞模型,遇到网络抖动就凉了
  3. 可维护性:IO线程数无法预估,资源利用率低

1.2 NIO模型

在这里插入图片描述

俗称IO多路复用模型,该线程模型中前端挂载一个Selector用于轮询各个Channel的IO事件,收到后Dispatch到后端Worker线程池去做实际的IO处理(读写等),Worker线程池可以有多种模式,取决于具体设计

主要特点

  1. IO多路复用
  2. 非阻塞

优点

  1. IO非阻塞,可靠性和效率都相应提高

缺点

  1. 轮询的效率可能不高,取决于底层使用的系统库函数(select/poll)
  2. 内存拷贝相关还是会阻塞

1.3 AIO模型

AIO模型跟NIO模型本质的区别是异步,这里异步的含义是指当数据处理完成之后才通知使用方,而NIO是数据就绪之后。

1.4 RPC性能三要素

  1. IO模型:决定了数据发送的效率,可靠性等
  2. 协议:通常内部协议性能会更优
  3. 线程模型:决定编解码、消息接收与返回等在哪个线程执行

2 gRPC client侧线程模型

gRPC client端可以划分出三种线程

  1. Caller线程:业务当前线程
  2. Worker线程(grpc-default-executor):请求处理与响应回调线程
  3. IO线程(grpc-nio-worker-ELG):使用Netty的ELG

以futureClient为例,一次client请求的线程切换如下图:

在这里插入图片描述

整体一次执行流程描述如下:

  1. 创建链接,通常是Delayed的模式,第一次创建Stream时候之前才会创建连接
  2. 创建Stream,代表发起一次请求,在Caller Thread完成
  3. 发送Header,将Header Frame投递到WriteQueue,Call Thread完成,ELG异步消费WriteQueue
  4. 发送Message,将Message Frame投递到WriteQueue,Call Thread完成,ELG异步消费WriteQueue
  5. 接收Header,这里完成一次从ELG -> Worker线程池的切换,需要注意的是如果创建Client时我们指定了directExecutor模式,那么将统一由ELG线程完成
  6. 接收Message,这里完成一次从ELG -> Worker线程池的切换,需要注意的是如果创建Client时我们指定了directExecutor模式,那么将统一由ELG线程完成
  7. 接收关闭Stream请求,线程切换同5,6,最终会回调Future的set方法
  8. Caller Thread通过Future.get获取到结果

3 gRPC server侧线程模型

gRPC server侧主要包括两个线程:

  1. Worker线程(grpc-default-executor):Server启动时候指定
  2. IO线程(grpc-nio-worker-ELG):使用Netty的ELG

以一次Unary请求为例,Server侧线程切换如下:

在这里插入图片描述

整体一次执行流程描述如下:

  1. 接收Client发送的创建Stream的请求,ELG -> Worker线程切换,最终创建一个ServerCall及其Listener
  2. 接收Client发送的Msg,ELG -> Worker线程切换,反序列化保存
  3. Client完成发送,ELG -> Worker线程切换,回调Server业务逻辑
  4. 处理完成发送Header,扔到WriteQueue,ELG异步消费发送Header Frame到Client
  5. 处理完成发送Message,扔到WriteQueue,ELG异步消费发送Message Frame到Client
  6. 完成全部消息发送,标记end of frame,对于unary而言跟5合成一步,扔到WriteQueue,ELG异步消费发送Message Frame到Client
  7. Client发送RstStream请求,并不一定会发送,取决于配置,回调Listener

综上完成了Client与Server线程模型的介绍,结合之前篇章gRPC API设计思路部分,相信大家可以更好的理解一次请求在gRPC内部是如何流转的。下面将介绍一个连接从建立到释放状态流转的过程,从另一种维度介绍gRPC是如何维护连接的。

4 gRPC链接状态机

gRPC内部在Channel构建到销毁的生命周期内,维护了该链接的整个状态的运转,了解内部具体的运转流程有助于我们更好的定位问题。gRPC内部链接主要分成如下几个状态:

  1. CONNECTING:代表Channel正在初始化建立连接,流程会涉及DNS解析、TCP建连、TLS握手等
  2. READY:成功建立连接,包括HTTP2协商,代表Channel可以正常收发数据
  3. TRANSIENT_FAILURE:建连失败或者CS之间网络问题导致,Channel最终会重新发起建立连接请求,gRPC提供了一套backoff Retry机制来保证不会出现重连风暴
  4. IDLE:Channel中长期没有请求或收到HTTP2的GO_AWAY信号会进入此状态,此时CS之间连接已经断开,一旦新请求发起会转移到CONNECTING。主要目的是保障SERVER连接数不会太大造成压力
  5. SHUTDOWN:Channel已经关闭,状态不可逆,新请求会立即失败掉,排队的请求会继续处理完

下图描述了五种状态之间的转换:

在这里插入图片描述

Java gRPC使用了grpc-netty-shaded库。该库是一个RPC库和框架,用于在Java中构建分布式系统。它可以与JDK 7一起使用,并支持Android设备上的Java客户端。另外,我还发现一个有关Java性能和内存使用情况的图形化工具,叫做Visual VM。这个工具可以用于监视本地和远程的Java虚拟机,识别和解决Java应用程序的性能问题。在你提到的引用中,也提到了Java Thread Sleep事件,它表示代码中存在手动调用Thread.sleep的行为。这个事件通常用于处理请求超时的场景,并且不会对整体性能产生影响。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [grpc-java:Java gRPC实现。 基于HTTP2的RPC](https://download.csdn.net/download/weixin_42138408/15241462)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [通过 HTTP/2 协议案例学习 Java & Netty 性能调优:工具、技巧与方法论](https://blog.csdn.net/BASK2311/article/details/130840661)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一棵___大树

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值