RPC

对于整条 RPC 调用链路(从 App 到网关再到各个服务系统),怎么设置 RPC 的超时时间,要考虑哪些问题?”

 

 

 

  • 结合 TP99 请求耗时:首先如果你要回答“超时时间设置和重传次数问题”,需要根据每一个微服务 TP99 的请求耗时,以及业务场景进行综合衡量。

  • RPC 调用方式:你要站在业务场景下,讲清楚网关调用各下游服务的串并行方式,服务之间是否存在上下服务依赖。

  • 分析核心服务:分析出哪些是核心服务,哪些是非核心服务,核心服务是否有备用方案,非核心服务是否有降级策略。

 

一次请求需要调用 3 次 RPC 服务,计算下来,RPC 服务需要承载大概 6 万次/s 的请求。那么你怎么设计 RPC 框架才能承载 6 万次/s 请求量呢?

优化 RPC 的网络通信性能: 高并发下选择高性能的网络编程 I/O 模型

选型合适的 RPC 序列化方式: 选择合适的序列化方式,进而提升封包和解包的性能

 

一次完整的 RPC 流程

因为 RPC 是远程调用,首先会涉及网络通信, 又因为 RPC 用于业务系统之间的数据交互,要保证数据传输的可靠性,所以它一般默认采用 TCP 来实现网络数据传输。

网络传输的数据必须是二进制数据,可是在 RPC 框架中,调用方请求的出入参数都是对象,对象不能直接在网络中传输,所以需要提前把对象转成可传输的二进制数据,转换算法还要可逆,这个过程就叫“序列化”和“反序列化”。

RPC 不会把请求参数的所有二进制数据一起发送到服务提供方机器上,而是拆分成好几个数据包(或者把好几个数据包封装成一个数据包),所以服务提供方可能一次获取多个或半个数据包,这也就是网络传输中的粘包和半包问题。为了解决这个问题,需要提前约定传输数据的格式,即“RPC 协议”

  • 数据头一般用于身份识别,包括协议标识、数据大小、请求类型、序列化类型等信息;

  • 消息体主要是请求的业务参数信息和扩展属性等。

 

如何选型序列化方式

  • JSON:Key-Value 结构的文本序列化框架,易用且应用最广泛,基于 HTTP 协议的 RPC 框架都会选择 JSON 序列化方式,但它的空间开销很大,在通信时需要更多的内存。

  • Hessian:一种紧凑的二进制序列化框架,在性能和体积上表现比较好。

  • Protobuf:Google 公司的序列化标准,序列化后体积相比 JSON、Hessian 还要小,兼容性也做得不错。

考虑时间与空间开销,切勿忽略兼容性。

在大量并发请求下,如果序列化的速度慢,势必会增加请求和响应的时间(时间开销)。另外,如果序列化后的传输数据体积较大,也会使网络吞吐量下降(空间开销)

如何提升网络通信性能

网络编程中的五个 I/O 模型:

  • 同步阻塞 I/O(BIO)

  • 同步非阻塞 I/O

  • I/O 多路复用(NIO)

  • 信号驱动

  • 以及异步 I/O(AIO)

实际开发工作,最为常用的是 BIO 和 NIO

 

 每当客户端发送一个连接请求给服务端,服务端都会启动一个新的线程去处理客户端连接的读写操作

  • Socket 连接数量受限,不适用于高并发场景;

  • 有两处阻塞,分别是等待用户发起连接,和等待用户发送数据。

NIO 网络模型,操作上是用一个线程处理多个连接,使得每一个工作线程都可以处理多个客户端的 Socket 请求,这样工作线程的利用率就能得到提升,所需的工作线程数量也随之减少。此时 NIO 的线程模型就变为 1 个工作线程对应多个客户端 Socket 的请求,这就是所谓的 I/O多路复用。

 

 既然服务端的工作线程可以服务于多个客户端的连接请求,那么具体由哪个工作线程服务于哪个客户端请求呢?

需要一个调度者去监控所有的客户端连接,比如当图中的客户端 A 的输入已经准备好后,就由这个调度者去通知服务端的工作线程,告诉它们由工作线程 1 去服务于客户端 A 的请求。这种思路就是 NIO 编程模型的基本原理,调度者就是 Selector 选择器。

NIO 比 BIO 提高了服务端工作线程的利用率,并增加了一个调度者,来实现 Socket 连接与 Socket 数据读写之间的分离。

 目前主流的 RPC 框架中,广泛使用的也是 I/O 多路复用模型,Linux 系统中的 select、poll、epoll等系统调用都是 I/O 多路复用的机制。

 

主从多线程模型

 

posted @ 2023-03-14 10:10  jiaozg  阅读(99)  评论(0)    收藏  举报