上一篇 (一)分布式RPC框架 文章对什么是RPC以及其原理做了介绍,那么我们现在继续来学习RPC框架的调用分类以及其框架性能。
RPC框架调用分类
RPC调用主要分为两种:同步调用 和 异步调用。
-
同步调用:客户端调用服务端方法,等待直到服务器端返回结果或者超时再继续自己的操作。
-
异步调用:客户端调用服务端方法,不再等待服务端返回,直接继续自己的操作。
1. 同步调用
在分布式微服务架构中,一个业务的调用会跨N(N≥2)个服务进程,整个调用链路上的同步调用等待的瓶颈会由最慢(或者最脆弱)的服务决定。比如A-B-C这样的一个调用链路,A同步调用B并等待返回结果,B同步调用C并等待返回结果,以此类推,就像一组此轮链,一级一级的传动,这很容易产生血崩效应。若C服务挂掉了,则会导致前面的服务全部因为等待超时儿占用大量不必要的线程资源。对于血崩效应,常用的解决方法有使用超时策略和熔断器机制
(1)超时策略
在服务调用链中,某个服务的故障可能会导致级联故障。调用服务的操作可以配置为执行超时,如果服务未能在这个时间内响应,就回复一个失败消息。然而这种策略可能会导致许多并发请求到同一个操作被阻塞,直到超时期限届满。这些阻塞的请求可能会存储关键的系统资源,如内存、线程、数据库连接等等。所以这些资源可能会枯竭,导致需要使用相同的资源系统出现故障。如果设定较短的超时时间可能有助于解决问题,但是一个请求从发出到收到成功或者失败消息需要的时间是不确定的。所以在分布式微服务架构下,我们需要根据成功调用服务器链的平均时间来合理配置服务器接口的超时时长。
(2)熔断器机制
熔断器的模式是使用断路器来检测故障是否得到解决,防止请求反复尝试执行一个可能会失败的操作,从而减少等待纠正故障的时间,相对于超时策略更加灵活。熔断器机制后续会详细的学习发出。
!!值得注意的是,RPC的同步确保请求送达对方并收到对方的响应,若没有收到响应,则框架会抛出TimeOut超时异常,这样的情况下,调用方是无法确定调用是成功还是失败的,需要根据业务场景(比如是否可以重入,幂等)选择重试和补偿策略。
2. 异步调用
PRC的异步调用意味着RPC框架不阻塞调用线程,调用方不需要立刻拿到返回结果,甚至调用方根本不关心返回结果。
从上面的RPC异步交互原理图中可清楚的得知,异步请求返回一个Future对象给调用方,以便调用方通过Future来获取返回值。下面来说说一个具体的Future实例吧,如下图所示:
从上图中可以得知,调用方通过服务网关(API Gateway)发起调用并等待结果,随后网关派发调用请求给后续服务,其主调用链路为 A->B->C, 其内部为异步调用,链路上不等待,最后由C 返回结果给服务网关。
其中,B又依赖两个子服务:B11和B22,B需要B11和B22的返回结果才能发起C的调用,因此在支路上B针对B11和B22调用是需要同步的。
!!注意在微服务架构下,大部分的服务调用都是同步的,异步调用的使用场景是在上游服务不会实时关注下游服务的调用结果的情况下使用,比如通过异步调用记录日志,通过异步调用在一定程度上可以提升服务性能,但不可滥用,否则会产生补课预料的后果。
以上就是RPC框架调用的分类说明,其中提到了RPC框架的性能,那么下面一起来看看RPC的性能。
RPC框架的性能
影响RPC框架性能的因素主要有下面几点:
- 网络IO模型: 在高并发状态下,阻塞式同步IO、非阻塞式同步IO或者多路IO模型对RPC服务器影响很大,特别是单位处理性能下对内存、CPU资源使用率的影响。
- 基于网络协议: RPC框架可选择的协议有HTTP协议、HTTP/2协议、TCP协议等。HTTP协议使用文本协议对传输内容进行编码,相对于采用二进制编码协议的TPC/IP协议码流更大。选择不同的协议对RPC框架的性能有一定的影响。目前没有采用UDP协议作为主要的传输协议。
- 消息封装格式: 消息封装格式的设计是影响RPC框架性能最重要的原因,这就是为什么几乎所有主流的RPC框架都会设计私有的消息封装格式。选择或者定义一直消息格式的封装要考虑的问题包括消息的易读性、描述单位内容时的消息大小、编码难度、解码难度、解决半包/粘包问题的难易度。Dubbo 消息体数据包含Dubbo 版本号、接口名称、接口版本、方法名称、参数类型列表、参数、附加信息等。
- Schema(模式)和序列化(Schema & Data Serialization): 序列化、反序列化的时间,序列化后数据的字节大小直接影响RPC框架的性能。
RPC框架与分布式服务框架
RPC框架的通信方式是点对点的,即服务消费者与服务提供者是点对点通信的。点对点通信包括通信、序列化、反序列化以及协议等内容。分布式服务框架不仅具有RPC框架的特性,还包括以下特性:
- 由多台服务器提供服务,具有负载均衡策略。
- 服务自动注册、发布。
- 服务治理。
当大规模的应用服务化之后,服务治理问题会慢慢暴露出来,纯粹的RPC框架服务治理能力都不健全,要解决这些问题,必须提供服务框架和服务治理来完成,单凭RPC框架无法解决服务治理问题。