深刻浅出 RPC - 浅出篇

近几年的项目中,服务化和微服务化渐渐成为中大型分布式系统架构的主流方式,而 RPC 在其中扮演着关键的做用。在平时的平常开发中咱们都在隐式或显式的使用 RPC,一些刚入行的程序员会感受 RPC 比较神秘,而一些有多年使用 RPC 经验的程序员虽然使用经验丰富,但有些对其原理也不甚了了。缺少对原理层面的理解,每每也会形成开发中的一些误用。java

本文分上下两篇《浅出篇》和《深刻篇》,其目标就是想尝试深刻浅出的分析下 RPC 本质,我老是这么认为理解了本质才能更好的应用。程序员

RPC 是什么?
RPC 的全称是 Remote Procedure Call 是一种进程间通讯方式。它容许程序调用另外一个地址空间(一般是共享网络的另外一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员不管是调用本地的仍是远程的,本质上编写的调用代码基本相同。算法

RPC 起源
RPC 这个概念术语在上世纪 80 年代由 Bruce Jay Nelson 提出。这里咱们追溯下当初开发 RPC 的原动机是什么?在 Nelson 的论文 "Implementing Remote Procedure Calls" 中他提到了几点:网络

1. 简单:RPC 概念的语义十分清晰和简单,这样创建分布式计算就更容易。
2. 高效:过程调用看起来十分简单并且高效。
3. 通用:在单机计算中过程每每是不一样算法部分间最重要的通讯机制。 
通俗一点说,就是通常程序员对于本地的过程调用很熟悉,那么咱们把 RPC 做成和本地调用彻底相似,那么就更容易被接受,使用起来毫无障碍。Nelson 的论文发表于 30 年前,其观点今天看来确实高瞻远瞩,今天咱们使用的 RPC 框架基本就是按这个目标来实现的。架构

RPC 结构
Nelson 的论文中指出实现 RPC 的程序包括 5 个部分:框架

1. User
2. User-stub
3. RPCRuntime
4. Server-stub
5. Server
这 5 个部分的关系以下图所示分布式

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

RPC 实现
Nelson 论文中给出的这个实现结构也成为后来你们参考的标准范本。大约 10 年前,我最先接触分布式计算时使用的 CORBAR 实现结构基本与此相似。CORBAR 为了解决异构平台的 RPC,使用了 IDL(Interface Definition Language)来定义远程接口,并将其映射到特定的平台语言中。后来大部分的跨语言平台 RPC 基本都采用了此类方式,好比咱们熟悉的 Web Service(SOAP),近年开源的 Thrift 等。他们大部分都经过 IDL 定义,并提供工具来映射生成不一样语言平台的 user-stub 和 server-stub,并经过框架库来提供 RPCRuntime 的支持。不过貌似每一个不一样的 RPC 框架都定义了各自不一样的 IDL 格式,致使程序员的学习成本进一步上升(苦逼啊),Web Service 尝试创建业界标准,无赖标准规范复杂而效率偏低,不然 Thrift 等更高效的 RPC 框架就不必出现了。微服务

IDL 是为了跨平台语言实现 RPC 不得已的选择,要解决更普遍的问题天然致使了更复杂的方案。而对于同一平台内的 RPC 而言显然不必搞个中间语言出来,例如 java 原生的 RMI,这样对于 java 程序员而言显得更直接简单,下降使用的学习成本。目前市面上提供的 RPC 框架已经可算是五花八门,百家争鸣了。须要根据实际使用场景谨慎选型,须要考虑的选型因素我以为至少包括下面几点:工具

1. 性能指标
2. 是否须要跨语言平台
3. 内网开放仍是公网开放
4. 开源 RPC 框架自己的质量、社区活跃度

总结 《浅出篇》大概就到这里结束了,谢谢你们的支持。

相关文章
相关标签/搜索