深入理解RPC

Posted 故里学Java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解RPC相关的知识,希望对你有一定的参考价值。

点击关注"故里学Java"

右上角"设为星标"好文章不错过

我觉得学习一项技术最好的方法就是跟着官方文档学,最近在深入学习 dubbo,就逛了一下 Dubbo 的官网,发现官方已经整理了很多比较好的博客文档,都是实打实的干活,建议大家有时间也可以看看。接下来我会整理一个专题来分享我在这个学习中记录的笔记,希望可以帮助到大家,今天分享第一篇,深入了解一下 RPC。

什么是 RPC?


RPC(Remote Procedure Call)--远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,也就是说两台服务器 A、B,一个应用部署在 A 服务器上,想要调用 B 服务器上应用提供的方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和表达调用的数据。

RPC 协议假定某些协议的存在,如 TCP 或 UDP,为通信程序之间携带信息数据。在 OSI 网络通信模型中,RPC 跨越了传输层和应用层,RPC 使得开发包括网络分布式多程序在内的应用程序更加容易。现在业界比较优秀的 RPC 框架有:Spring Cloud、Dubbo、Thrift 等。

RPC 的结构


Bruce Jay Nelson 是最早提出 RPC 这个概念术语的,在他的论文中指出,实现 RPC 的程序包括 5 个部分:User、User-stub、RPCRuntime、Server-stub、Server。

这里 User 就是 client 端,当 user 想发起一个远程调用时,它实际是通过本地调用 User-stub。User-stub 负责将调用的接口、方法和参数通过约定的协议规范进行编码并通过本地 RPCRuntime 实例传输到远端的实例。远端 RPCRuntime 实例收到请求后交给 Server-stub 进行解码后发起本地调用,调用结果再返回给 User 端。

上边的简略的介绍 RPC 实现概念,下边来详细看看它由哪些组件组成。

RPC 服务方通过 RpcServer 去导出(export)远程接口方法,而客户方通过 RpcClient 去引入(import)远程接口方法。客户方像调用本地方法一样去调用远程接口方法,RPC 框架提供接口的代理实现,实际的调用将委托给代理 RpcProxy 。代理封装调用信息并将调用转交给 RpcInvoker 去实际执行。在客户端的 RpcInvoker 通过连接器 RpcConnector 去维持与服务端的通道 RpcChannel,并使用 RpcProtocol 执行协议编码(encode)并将编码后的请求消息通过通道发送给服务方。

RPC 服务端接收器 RpcAcceptor 接收客户端的调用请求,同样使用 RpcProtocol 执行协议解码(decode)。解码后的调用信息传递给 RpcProcessor 去控制处理调用过程,最后再委托调用给 RpcInvoker 去实际执行并返回调用结果。如下是各个部分的详细职责:

  • RPCServer:负责导出(export)远程接口

  • RPCClient:负责导入(export)远程接口的代理实现

  • RPCProxy:远程接口的代理实现

  • RPCInvoker:

    • 客户方实现:负责编码调用信息和发送调用请求到服务方并等待调用结果返回
    • 服务方实现:负责调用服务端口的具体实现并返回调用结果
  • RPCProtocol:负责协议编码/解码

  • RPCConnector:负责维护客户方和服务方的连接通道和发送数据到服务方

  • PRCAcceptor:负责接收客户方请求并返回请求结果

  • RPCProcessor:负责在服务控制调用过程,包括管理线程池、调用超时等

  • RPCChannel:数据传输通道

RPC 工作原理


RPC 的设计由 Client,Client stub,Network ,Server stub,Server 构成。其中 Client 就是用来调用服务的,Cient stub 是用来把调用的方法和参数序列化的(因为要在网络中传输,必须要把对象转变成字节),Network 用来传输这些信息到 Server stub, Server stub 用来把这些信息反序列化的,Server 就是服务的提供者,最终调用的就是 Server 提供的方法。

  1. Client 像调用本地服务似的调用远程服务;
  2. Client stub 接收到调用后,将方法、参数序列化
  3. 客户端通过 sockets 将消息发送到服务端
  4. Server stub 收到消息后进行解码(将消息对象反序列化)
  5. Server stub 根据解码结果调用本地的服务
  6. 本地服务执行(对于服务端来说是本地执行)并将结果返回给 Server stub
  7. Server stub 将返回结果打包成消息(将结果消息对象序列化)
  8. 服务端通过 sockets 将消息发送到客户端
  9. Client stub 接收到结果消息,并进行解码(将结果消息反序列化)
  10. 客户端得到最终结果。

RPC 调用分以下两种:


  1. 同步调用:客户方等待调用执行完成并返回结果。
  2. 异步调用:客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。若客户方不关心调用返回结果,则变成单向异步调用,单向调用不用返回结果。

RPC 可以做什么?


RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制,让使用者不必显式的区分本地调用和远程调用,在之前给出的一种实现结构,基于 stub 的结构来实现。下面我们将具体细化 stub 结构的实现。

  • 可以做到分布式,现代化的微服务
  • 部署灵活
  • 解耦服务
  • 扩展性强

RPC 的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里。通过 RPC 能解耦服务,这才是使用 RPC 的真正目的。

总结


本文介绍了一些 RPC 的原理,到这里相信大家对于 RPC 有了一定理解,其实实现一个 RPC 并不难,难的是实现一个高性能高可靠的 RPC 框架。


- END -


好文推





大家好,我是"故里学Java"公号作者,你可以叫我"故里"。

一直坚信技术能改变生活,愿保持初心,加油技术人!

你们点个在看故里会兴奋一晚上睡不着~


以上是关于深入理解RPC的主要内容,如果未能解决你的问题,请参考以下文章

服务之间的调用之RPC深入理解

手写RPC,深入底层理解整个RPC通信

RPC 专题深入理解 RPC 之服务注册与发现篇

深入理解RPC框架的序列化方案

深入理解Linux RPC - 从Linux RPC到Android Binder

早鸟报名:深入理解Linux RPC - 从Linux RPC到Android Binder