RPC框架详解

一、什么是RPC?

  • RPC(Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方法。就是从一台客户端上通过参数传递的方式调用另一台服务器上的一个函数或方法,并得到返回的结果。
  • RPC会隐藏底层的通讯细节(不需要直接处理Socket通信或Http通讯)。
  • 客户端发起请求,服务端返回响应,RPC在使用形式上像调用本地函数一样去调用远程的函数。

RPC框架详解_第1张图片
为什么要用RPC?
RPC的目标就是让构建分布式应用更容易,在远程调用时,能够像本地调用一样方便,让调用者感觉不到远程调用的逻辑。

二、RPC的核心功能

RPC框架详解_第2张图片
一个RPC的核心功能主要由以下五部分组成:

  1. 客户端(Client): 服务调用方。
  2. 客户端存根(Client Stub): 存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端。
  3. 服务端存根(Server Stub): 接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理。
  4. 服务端(Server): 服务的真正提供者。
  5. 网络传输模块(Network Service): 底层传输,可以是TCP或HTTP。

一次RPC调用流程如下:

  • 服务消费者(Client 客户端)通过本地调用的方式调用服务。
  • 客户端存根(Client Stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体。
  • 客户端存根(Client Stub)找到远程的服务地址,并且将消息通过网络发送给服务端。
  • 服务端存根(Server Stub)收到消息后进行解码(反序列化操作)。
  • 服务端存根(Server Stub)根据解码结果调用本地的服务进行相关处理
  • 服务端(Server)本地服务业务处理。
  • 处理结果返回给服务端存根(Server Stub)。
  • 服务端存根(Server Stub)序列化结果。
  • 服务端存根(Server Stub)将结果通过网络发送至消费方。
  • 客户端存根(Client Stub)接收到消息,并进行解码(反序列化)。
  • 服务消费方得到最终结果。

RPC的核心功能的实现:
1)服务寻址
服务寻址可以使用Call ID映射。在RPC中,所有的函数都必须有自己的一个ID,这个ID在所有进程中都是唯一确定的。
客户端在做远程调用时,必须附上这个ID。然后我们还需要在客户端和服务端分别维护一个函数和Call ID的对应表。
当客户端进行远程调用时,它就查一下这个表,找出相应的Call ID,然后把它传给服务端。服务端也通过查表来确定客户端需要调用的函数,然后再执行相应函数的代码。

实现方式:服务注册中心。
首先你需要一个服务注册中心去查询对方服务都有哪些实例。Dubbo的服务注册中心是可以配置的,官方推荐使用Zookeeper。

实现案例:RMI(Remote Method Invocation,远程方法调用)也就是RPC本身的实现方式。
RPC框架详解_第3张图片
Registry(服务发现):借助JNDI发布并调用了RMI服务,实际上,JNDI就是一个注册表,服务端将服务对象放入到注册表中,客户端从注册表中获取服务对象。
Registry 是个很重要的功能,当服务端开发完服务之后,要对外暴露,如果没有服务注册,则客户端是无从调用的,即使服务端的服务就在那里。

2)序列化和反序列化
在远程调用时,客户端和服务端是不同的进程,不能通过内存来传递参数。
这时候就需要客户端把参数先转成一个字节流,传给服务端,服务端再将字节流转成自己能读取的格式。
同理,从服务端返回的值也需要序列化反序列化的过程。

只有二进制数据才能在网络中传输,序列化和反序列化的定义是:

  • 将对象转换成二进制流的过程叫做序列化
  • 将二进制流转换成对象的过程叫做反序列化

3)网络传输
远程调用往往用在网络上,客户端和服务端是通过网络链接的。
所有数据都需要通过网络传输,因此就需要有一个网络传输层。网络传输层需要把Call ID和序列化后的参数字节流传给服务端,然后再将序列化后的调用结果返回给客户端。

网络传输协议: TCP协议,UDP协议,HTTP协议。

基于TCP协议的RPC调用:
由客户端与服务端建立Socket连接,并由客户端通过Socket将需要调用的接口名称,方法名称和参数序列化传递给服务端,服务端反序列化后再利用反射调用相关方法。
RMI 便是在 TCP 协议上传递可序列化的 Java 对象。

基于HTTP协议的RPC调用:
由客户端向服务端发送请求,这种请求的方式可能是 GET、POST、PUT、DELETE 等中的一种,服务端可能会根据不同的请求方式做出不同的处理,或者某个方法只允许某种请求方式。而调用的具体方法则是根据 URL 进行方法调用,而方法所需要的参数可能是对客户端传输过去的 XML 数据或者 JSON 数据解析后的结果,服务端返回 JOSN 或者 XML 的数据结果。
Tomcat就是再HTTP协议上做RPC调用。HttpClient也是。

两种方式的对比:

  • TCP协议:
    优点:TCP协议处于协议栈的下层,能更加灵活的对协议字段进行定制,减少网络开销,提高性能,实现更大的吞吐量和并发数。
    缺点:需要更多关注底层的东西,对不同平台需要开发不同的工具包来进行请求发送和相应解析。

  • HTTP协议:
    优点:使用简单,可以使用JSON和XML格式的请求或响应数据。
    缺点:HTTP是上层协议,发送同等内容的信息,所占用的字节数更高。效率更低,传输占用的时间也会更长。

三、对比Restful API 和RCP

RESTful API 架构:

  • 资源:网络上的一个实体。
  • 统一接口:RESTful 架构风格规定,数据的元操作,即 CRUD(Create,Read,Update 和 Delete,即数据的增删查改)操作,分别对应于 HTTP 方法:GET 用来获取资源,POST 用来新建资源(也可以用于更新资源),PUT 用来更新资源,DELETE 用来删除资源,这样就统一了数据操作的接口,仅通过 HTTP 方法,就可以完成对数据的所有增删查改工作。
  • URL:可以用一个 URI(统一资源定位符)指向资源,即每个 URI 都对应一个特定的资源。
  • 无状态:所谓无状态的,即所有的资源,都可以通过 URI 定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。

对比RPC:

  1. 面向对象不同:
    RESTful 是面向资源的设计架构,但在系统中有很多对象不能抽象成资源,比如登录,修改密码等而 RPC 可以通过动作去操作资源。所以在操作的全面性上 RPC 大于 RESTful。

  2. 传输效率:
    RPC 效率更高。RPC,使用自定义的 TCP 协议,可以让请求报文体积更小,或者使用 HTTP2 协议,也可以很好的减少报文的体积,提高传输效率。

  3. 复杂度:
    RPC 实现需要实现编码,序列化,网络传输等。而 RESTful 不要关注这些,RESTful 实现更简单。

  4. 灵活性:
    HTTP 相对更规范,更标准,更通用,无论哪种语言都支持 HTTP 协议。
    RPC 可以实现跨语言调用,但整体灵活性不如 RESTful。

四、RPC使用场景

  • 长链接: 不必每次通信都要像 HTTP 一样去 3 次握手,减少了网络开销。

  • 注册发布机制: RPC 框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。

  • 安全性: 没有暴露资源操作。

  • 微服务支持: 就是最近流行的服务化架构、服务化治理,RPC 框架是一个强力的支撑。

你可能感兴趣的:(微服务,RPC)