RPC(Remote Procedure Call,远程过程调用)是一种进程间的通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式地编码远程调用的细节,即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。目前,主流的平台都支持各种远程调用技术,以满足分布式系统架构中不同系统之间的远程通信和相互调用。
完整的RPC框架主要包含4个核心的组件:Client、Server、Client Stub以及Server Stub,具体如图3-1所示。
图3-1 RPC核心组件图
RPC调用过程如图3-2所示。
图3-2 RPC调用过程
(1)客户端(Client)以本地调用方式调用服务(依赖服务接口,以接口的方式调用)。
(2)客户端存根(Client Stub)接收到调用请求后,负责将方法、参数等组装成能够进行网络传输的消息体(将消息体对象序列化为二进制)。
(3)客户端通过Socket将消息发送到服务端。
(4)服务端存根(Server Stub)收到消息后对消息进行解码(将消息对象反序列化)。
(5)服务端存根(Server Stub)根据解码结果调用本地的服务(利用反射原理)。
(6)本地服务执行并将结果返回给服务端存根(Server Stub)。
(7)服务端存根(Server Stub)将返回结果打包成消息(将结果消息对象序列化)。
(8)服务端(Server)通过Socket将消息发送到客户端。
(9)客户端存根(Client Stub)接收到结果消息,并进行解码(将结果消息反序列化)。
(10)客户端(Client)得到最终结果。
无论是哪种类型的数据,最终都需要转换成二进制流在网络上进行传输,数据的发送方需要将对象转换为二进制流,而数据的接收方则需要把二进制流再恢复为对象。RPC的目标是把(2)、(3)、(4)、(7)、(8)、(9)这些步骤都封装起来,具体如图3-3所示。
图3-3 RPC框架原理图
RPC调用主要分为两种:同步调用和异步调用
在分布式微服务架构中,一个业务的调用会跨N(N≥2)个服务进程,整个调用链路上的同步调用等待的瓶颈会由最慢(或脆弱)的服务决定。比如A-B-C这样一个调用链路,A同步调用B并等待返回结果,B同步调用C并等待返回结果,以此类推,就像一组齿轮链,级级传动,这很容易产生雪崩效应。若C服务挂了,则会导致前面的服务全部因为等待超时而占用大量不必要的线程资源。对于雪崩效应,常用解决方法有:使用超时策略和熔断器机制。
(1)超时策略: 在一个服务调用链中,某个服务的故障可能会导致级联故障。调用服务的操作可以配置为执行超时,如果服务未能在这个时间内响应,就回复一个失败消息。然而,这种策略可能会导致许多并发请求到同一个操作被阻塞,直到超时期限届满。这些阻塞的请求可能会存储关键的系统资源,如内存、线程、数据库连接等。因此,这些资源可能会枯竭,导致需要使用相同的资源系统出现故障。设置较短的超时可能有助于解决这个问题,但是一个请求从发出到收到成功或者失败的消息需要的时间是不确定的。在分布式微服务架构下,我们需要根据成功调用一个服务调用链的平均时间来合理配置服务接口超时时间。
(2)熔断器机制: 熔断器的模式使用断路器来检测故障是否已得到解决,防止请求反复尝试执行一个可能会失败的操作,从而减少等待纠正故障的时间,相对于超时策略更加灵活。熔断器机制在后续的章节中会有详细描述。
RPC的同步调用确保请求送达对方并收到对方响应,若没有收到响应,则框架抛出Timeout超时异常。这种情况下,调用方是无法确定调用是成功还是失败的,需要根据业务场景(是否可重入,幂等)选择重试和补偿策略。
RPC的异步调用意味着RPC框架不阻塞调用方线程,调用方不需要立刻拿到返回结果,甚至调用方根本就不关心返回结果。RPC的异步交互场景如图3-4所示。
图3-4 RPC异步交互原理
由图3-4可知,异步请求返回一个Future对象给调用方,以便调用方可以通过Future来获取返回值。有了Future机制,我们再来看一个具体实例,如图3-5所示。
图3-5 RPC异步交互具体实例
调用方通过服务网关(API Gateway)发起调用并等待结果,随后网关派发调用请求给后续服务,其主调用链路为A-B-C,其内部为异步调用,链路上不等待,最后由C返回结果给服务网关。其中,B又依赖两个子服务:B11和B22,B需要B11和B22的返回结果才能发起C调用,因此在支线上B针对B11和B22调用就需要是同步的。
在微服务架构下,大部分的服务调用都是同步调用,异步调用的使用场景:上游服务不会实时关注下游服务的调用结果,比如通过异步调用记录日志。通过异步调用在一定程度上可以提升服务性能,但不可滥用,否则会产生不可预料的结果。
影响RPC框架性能的因素如下:
RPC框架的通信方式是点对点,即服务消费者与服务提供者是点对点通信的。点对点通信包括通信、序列化、反序列化以及协议等内容。分布式服务框架不仅具有RPC框架的特性,还包括以下特性:
当大规模的应用服务化之后,服务治理问题会慢慢暴露出来,纯粹的RPC框架服务治理能力都不健全,要解决这些问题,必须通过服务框架和服务治理来完成,单凭RPC框架无法解决服务治理问题。