RPC|青训营

88 阅读6分钟

RPC

基本概念

RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务。

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。 也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。为什么要用RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数;

RPC是一种技术思想而非一种规范或协议。

常见RPC技术和框架有:

应用级的服务框架:阿里的Dubbo/DubboX、Google的gRPC、Spring Boot/Spring\nCloud、Facebook的Thrift、Twitfer的Finagle等。

远程通讯协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。

通讯框架:MINAhe Netty。

ps:Google的gRPC框架是基于HTTP2协议实现的,底层使用到了Netty框架的支持。

RPC框架

1、一个典型的RPC的使用场景中,包含了服务发现、负载、容错、网络传输、序列化等组件,其中“PRC协议”就指明了程序如何进行网络传输和序列化。

2、RPC的核心功能

一个PRC的核心功能主要有5个部分组成,分别是:客户端、客户端Stub、网络传输模块、服务端Stub、服务端等。

下面分别介绍核心RPC框架的重要组成:

1、客户端(Client):服务调用方。

2、客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端。

3、服务端存根(Server Stub):接受客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理。

4、服务端(Server):服务的真正提供者。

5、Network Service:底层传输,可以是TPC或HTTP。

一次RPC调用流程如下:

1、服务消费者(Client 客户端)通过本地调用的方式调用服务。

2、客户端存根(Client Stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体。

3、客户端存根(Client Stub)找到远程的服务地址,并且将消息通过网络发送给服务端。

4、服务端存根(Server Stub)收到消息后进行解码(反序列化操作)。

5、服务端存根(Server Stub)根据解码结果调用本地的服务进行相关处理。

6、服务端(Server)本地服务业务处理。

7、处理结果返回给服务端存根(Server Stub)。

8、服务端存根(Server Stub)序列化结果。

9、服务端存根(Server Stub)将结果通过网络发送至消费方。

10、客户端存根(Client Stub)接受到消息,并进行解码(反序列化)。

11、服务消费方得到最终结果。

有关RPC知识

RPC核心功能实现技术点

透明化远程服务调用:字节码生成,JDK动态代理

编码与解码。

服务寻址:Call ID映射,可以直接使用函数字符串,也可以使用整数ID。映射表一般就是一个哈希表。

数据流的序列化和反序列化:可以自己写,也可以使用Protobuf或者FlatBuffers之类的。

网络传输:可以自己写Socket,或者调用Asio,Zero\nMQ,Netty之类。在RPC中可选的网络传输方式有多种,可以选择TCP协议、UDP协议、HTTP协议

RPC要素

Client:RPC协议的调用方。就像上文所描述的那样,最理想的情况是RPC Client在完全不知道有RPC框架存在的情况下发起对远程服务的调用。但实际情况来说Client或多或少的都需要指定RPC框架的一些细节。

Server:在RPC规范中,这个Server并不是提供RPC服务器IP、端口监听的模块。而是远程服务方法的具体实现(在JAVA中就是RPC服务接口的具体实现)。其中的代码是最普通的和业务相关的代码,甚至其接口实现类本身都不知道将被某一个RPC远程客户端调用。

Stub/Proxy:RPC代理存在于客户端,因为要实现客户端对RPC框架“透明”调用,那么客户端不可能自行去管理消息格式、不可能自己去管理网络传输协议,也不可能自己去判断调用过程是否有异常。这一切工作在客户端都是交给RPC框架中的“代理”层来处理的。

Message Protocol:在上文我们已经说到,一次完整的client-server的交互肯定是携带某种两端都能识别的,共同约定的消息格式。RPC的消息管理层专门对网络传输所承载的消息信息进行编号和解码操作。**目前流行的技术趋势是不同的RPC实现,为了加强自身框架的效率都有一套(或者几套)私有的消息格式。**例如前文所讲到的RMI框架使用的消息协议为JRMP;后文我们将详细讲解的RPC框架Thrift也有私有的消息协议,“- Transfer/Network Protocol”(当然它还支持一些通用的消息格式,如JSON)。

Transfer/Network Protocol:传输协议层负责管理RPC框架所使用的网络协议、网络IO模型。例如Hessian的传输协议基于HTTP(应用层协议);而Thrift的传输协议基于TCP(传输层协议)。传输层还需要统一RPC客户端和RPC服务端所使用的IO模型;