《凤凰架构》-RPC vs REST

Posted 七路灯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《凤凰架构》-RPC vs REST相关的知识,希望对你有一定的参考价值。


周志明《凤凰架构:构建可靠的大型分布式系统》
https://icyfenix.cn/

RPC发展史、REST风格编程思想、两者的区别和联系


1
 RPC

RPC出现的最初目的,就是为了让计算机能够跟调用本地方法一样去调用远程方法。


进程间通信(Inter-Process Communication,IPC)方法:

  • 管道(Pipe):类似于两个进程间的桥梁,传递少量的字符流和字节流。如:ps -ef | grep java

  • 信号(Signal):通知目标进程有某种事件发生。如:kill -9 pid

  • 信号量(Semaphore):信号量用于两个进程之间同步协作手段。如:wait(),notify()

  • 消息队列(Message Queue):以上三种方式只适合传递传递少量信息,消息队列用于进程间数据量较多的通信。

  • 共享内存(Shared Memory):允许多个进程访问同一块公共的内存空间,这是效率最高的进程间通信形式。

  • 套接字接口(Socket):以上两种方式只适合单机多进程间的通信,套接字接口是更为普适的进程间通信机制,可用于不同机器之间的进程通信。

通信的成本

最后一种基于套接字接口的通信方式(IPC Socket),它不仅适用于本地相同机器的不同进程间通信,由于 Socket 是网络栈的统一接口,它也理所当然地能支持基于网络的跨机器的进程间通信。


由于 Socket 是各个操作系统都有提供的标准接口,完全有可能把远程方法调用的通信细节隐藏在操作系统底层,从应用层面上看来可以做到远程调用与本地的进程间通信在编码上完全一致。但这种透明的调用形式却反而造成了程序员误以为通信是无成本的假象。


在“透明的 RPC 调用”一度成为主流范式的时候,Andrew Tanenbaum教授对此提出了一系列质问。论文的中心观点是:本地调用与远程调用当做一样处理,这是犯了方向性的错误,把系统间的调用做成透明,反而会增加程序员工作的复杂度。


透明通信的支持者有之,反对者有之,经过此后几年的发展,逐渐证明了Andrew Tanenbaum教授的预言是正确的。最终大佬们共同总结了通过网络进行分布式运算的八宗罪。


潜台词就是如果远程服务调用要弄透明化的话,就必须为这些罪过买单。至此,RPC 应该是一种高层次的或者说语言层次的特征,而不是像 IPC 那样,是低层次的或者说系统层次的特征成为工业界、学术界的主流观点。


RPC三个基本问题
  • 如何表示数据:就是序列化与反序列化。Web Service 的XML Serialization

  • 如何传递数据:通常指的是应用层协议,实际传输一般是基于标准的 TCP、UDP 等标准的传输层协议来完成的。Web Service 的Simple Object Access Protocol(SOAP)

  • 如何确定方法:一套语言无关的接口描述语言。Web Service 的Web Service Description Language(WSDL)


RPC的统一和分裂

统一

CORBA本身设计得实在是太过于啰嗦繁琐,制定的规范晦涩难懂脱离实际,没有把握住统一 RPC 的大好机遇。


后来XML 1.0 发布,并成为W3C的推荐标准,随后SOAP 1.0规范的发布,它代表着一种被称为“Web Service”的全新的 RPC 协议的诞生。随后提交给 W3C 投票成为国际标准,所以也被称为W3C Web Service。Web Service 采用了 XML 作为远程过程调用的序列化、接口描述、服务发现等所有编码的载体。


Web Service 的一大缺点是它那过于严格的数据和接口定义所带来的性能问题,XML本身信息密度就相对低下,Web Service又是跨语言的 RPC 协议,一个简单的字段为了不会产生歧义,XML严格描述的话,往往比原来多出几十倍的空间。

另外一点是,它希望在一套协议上一揽子解决分布式计算中可能遇到的所有问题,除它本身包括的 SOAP、WSDL、UDDI 协议外,还有一堆WS-*命名的、用于解决事务、一致性、事件、通知、业务描述、安全、防重放等子功能协议,这对开发者造成了非常沉重的学习负担。


分裂

由于一直没有一个同时满足以上三点的“完美 RPC 协议”出现。今时今日,任何一款具有生命力的 RPC 框架,都不再去追求大而全的“完美”,而是有自己的针对性特点作为主要的发展方向。


  • 朝着面向对象发展:RMI(Sun/Oracle)、.NET Remoting

  • 朝着性能发展,代表为 gRPC(Google)、Thrift(Facebook/Apache)

  • 朝着简化发展,代表为 JSON-RPC


到了最近几年,RPC 框架有明显的朝着更高层次(不仅仅负责调用远程服务,还管理远程服务)与插件化方向发展的趋势,不再追求独立地解决 RPC 的全部三个问题(表示数据、传递数据、表示方法),而是将一部分功能设计成扩展点,让用户自己去选择。

框架聚焦于提供核心的、更高层次的能力,譬如提供负载均衡、服务注册、可观察性等方面的支持。这一类框架的代表有 Facebook 的 Thrift 与阿里的 Dubbo。


2
 REST

REST并不是一种远程服务调用协议,它甚至就不是一种协议。虽然它有一些指导原则,但实际上并不受任何强制的约束。经常会有人批评说,某个系统接口“设计得不够 RESTful”,其实这句话本身就有些争议。因为 REST 只能说是一种风格。


REST是“表征状态转移”(Representational State Transfer)的缩写。可以理解为是“HTT”(Hyper Text Transfer,超文本传输)的进一步抽象,它们就像是接口与实现类之间的关系。


REST中关键概念:(以阅读文章为例)

  • 资源(Resource):可以将其视作是某种信息、数据。如:文章的内容,无论是网页还是报纸,你阅读的仍是同一个“资源”

  • 表征(Representation):指信息与用户交互时的表示形式。如:文章的PDF、Markdown等表现形式

  • 状态(State):在特定语境中才能产生的上下文信息就被称为“状态”。如:请求“下一篇”文章,依赖当前正在阅读的文章

  • 转移(Transfer):服务器通过某种方式,把“用户当前阅读的文章”转变成“下一篇文章”,这就被称为“表征状态转移”


RESTful的系统

REST风格的系统应该满足以下六大原则

  • 服务端与客户端分离(Client-Server)

  • 无状态(Stateless)

  • 可缓存(Cacheability)

  • 分层系统(Layered System)

  • 统一接口(Uniform Interface)

  • 按需代码(Code-On-Demand)


REST以资源为主体进行服务设计的风格,带来了什么好处:

  • 降低的服务接口的学习成本

  • 资源天然具有集合与层次结构

  • REST 绑定于 HTTP 协议


RMM成熟度模型

  • 0级. The Swamp of Plain Old XML:完全不REST,是RPC的风格

  • 1级. Resources:引入资源的概念

  • 2级. HTTP Verbs:引入统一接口,映射到HTTP协议的方法上(目前大部分的系统能够达到的REST界别)


编程思想的立场不同:

  • 面向过程编程时,为什么要以算法和处理过程为中心,输入数据,输出结果?当然是为了符合计算机世界中主流的交互方式。

  • 面向对象编程时,为什么要将数据和行为统一起来、封装成对象?当然是为了符合现实世界的主流的交互方式。

  • 面向资源编程时,为什么要将数据(资源)作为抽象的主体,把行为看作是统一的接口?当然是为了符合网络世界的主流的交互方式。


3
 RPC vs REST

REST 与 RPC 在思想上差异的核心是抽象的目标不一样,即面向资源的编程思想与面向过程的编程思想两者之间的区别。


至于使用范围,REST 与 RPC 作为主流的两种远程调用方式,在使用上是确有重合的,但重合的区域有多大就见仁见智了。


RPC一些发展方向,如分布式对象、提升调用效率、简化调用复杂性。

  • 分布式对象:这一条线的应用与 REST 可以说是毫无关联;

  • 提升调用效率:REST提升传输效率的潜力有限,对于传输协议、序列化器这两点都不会有什么选择的权力

  • 简化调用复杂性:追求简化调用的场景,众多 RPC 里也就 JSON-RPC 有机会与 REST 竞争


我们今天再去看这两种编程思想,虽然它们出现的时间有先后,但在人类使用计算机语言来处理数据的工作中,无论用哪种思维来抽象问题都是合乎逻辑的。


END




以上是关于《凤凰架构》-RPC vs REST的主要内容,如果未能解决你的问题,请参考以下文章

gRPC vs REST:两种API架构风格的对比

4 种主流的 API 架构风格对比

REST与RPC区别?

谈谈自己对rest和RPC的理解

gRPC vs REST:两种API架构风格的对比

GraphQL vs REST API 架构,谁更胜一筹?