其他分享
首页 > 其他分享> > 远程服务调用PRC发展史

远程服务调用PRC发展史

作者:互联网

本文是《凤凰架构》一书的读书笔记。

img

RPC 调用简介

RPC(远程服务调用)是指位于互不重合的内存地址空间中(可以是一台机器也可以是不同网络分区的不同机器)的两个程序,在语言层面上,以同步的方式使用带宽有限的信道来传输程序控制信息。

通过网络进行分布式运算的八宗罪(8 Fallaciesof Distributed Computing)

image-20210727170337843

RPC协议要解决的三个问题

1. 如何表示数据(如何进行序列化)

每种RPC协议都应该要有对应的序列化协议。

2. 如何传递数据(使用什么协议来传递数据)

如何传递数据,准确地说,是指如何通过网络,在两个服务的Endpoint之间相互操作、交换数据。

两个服务交互数据不是只扔个序列化数据流来表示参数和结果就行许多在此之外的信息,譬如异常、超时、安全、认证、授权、事务等,都可能产生双方需要交换信息的需求。在计算机科学中,专门有一个名词“Wire Protocol”来表示这种两个Endpoint之间交换这类数据的行为,常见的Wire Protocol如下。

3. 如何表示方法

确定表示方法在本地方法调用中并不是太大的问题,编译器或者解释器会根据语言规范,将调用的方法签名转换为进程空间中子过程入口位置的指针。不过一旦要考虑不同语言,事情又立刻麻烦起来,每种语言的方法签名都可能有差别,所以“如何表示同一个方法”“如何找到对应的方法”还是需要一个统一的跨语言的标准才行。

这个标准可以非常简单,譬如直接给程序的每个方法都规定一个唯一的、在任何机器上都绝不重复的编号,调用时压根不管它是什么方法、签名是如何定义的,直接传这个编号就能找到对应的方法。

类似地,用于表示方法的协议还有:

没有一个简单、通用、高性能的协议能同时解决上面的问题

面向透明的、简单的RPC协议,如DCE/RPC、DCOM、Java RMI,要么依赖于操作系统,要么依赖于特定语言,总有一些先天约束;

那些面向通用的、普适的RPC协议,如CORBA,就无法逃过使用复杂性的困扰,CORBA烦琐的OMGIDL、ORB都是很好的佐证;

而那些意图通过技术手段来屏蔽复杂性的RPC协议,如Web Service,又不免受到性能问题的束缚。

简单、普适、高性能这三点,似乎真的很难同时满足。

各有侧重点的RPC

由于一直没有一个同时满足以上三点的“完美RPC协议”出现,所以远程服务器调用这个小小的领域,逐渐进入群雄混战、百家争鸣的战国时代,距离“统一”越来越远,并一直延续至今。现在,已经相继出现过RMI(Sun/Oracle)、Thrift(Facebook/Apache)、Dubbo(阿里巴巴/Apache)、gRPC(Google)、Motan1/2(新浪)、Finagle(Twitter)、brpc(百度/Apache)、.NETRemoting(微软)、Arvo(Hadoop)、JSON-RPC 2.0(公开规范,JSON-RPC工作组)等难以穷举的协议和框架。这些RPC功能、特点不尽相同,有的是某种语言私有,有的支持跨越多种语言,有的运行在应用层HTTP协议之上,有的直接运行于传输层TCP/UDP协议之上,但并不存在哪一款是“最完美的RPC”。今时今日,任何一款具有生命力的RPC框架,都不再去追求大而全的“完美”,而是以某个具有针对性的特点作为主要的发展方向。

到了最近几年,RPC框架有明显向更高层次(不仅仅负责调用远程服务,还管理远程服务)与插件化方向发展的趋势,不再追求独立地解决RPC的全部三个问题(表示数据、传递数据、表示方法),而是将一部分功能设计成扩展点,让用户自己选择。框架聚焦于提供核心的、更高层次的能力,譬如提供负载均衡、服务注册、可观察性等方面的支持。这一类框架的代表有Facebook的Thrift与阿里的Dubbo

Dubbo默认有自己的传输协议(Dubbo协议),同时也支持其他协议;默认采用Hessian 2作为序列化器,如果你有JSON的需求,可以替换为Fastjson,如果你对性能有更高的追求,可以替换为Kryo、FST、Protocol Buffers等效率更好的序列化器,如果你不想依赖其他组件库,也可以直接使用JDK自带的序列化器。这种设计在一定程度上缓和了RPC框架必须取舍、难以完美的缺憾。

标签:协议,发展史,Protocol,PRC,Web,JSON,RPC,调用,序列化
来源: https://www.cnblogs.com/54chensongxia/p/15067341.html