RPC 是一种高级通信范例,允许一台计算机中的程序调用另一台计算机的子程序,就像调用本地程序一样(本地函数调用:同一个地址空间/内存,通过栈实现)。RPC 属于 C/S 模式,通过发送请求-接受回应进行信息交互。
0x01 常见的 RPC 实现
RPC 的具体实现包含一些约定好的规范,且很多时候需要像 ajax 一样由开发者自己编写服务器和客户端代码,而对于 gRPC 这样的框架则具备更严格的规范。
-
XML-RPC:通过 XML 将调用函数封装,并使用 HTTP 协议作为发送机制。由于XML的文本性质,性能较低
-
JSON-RPC:类似于 XML-RPC,只定义一些数据类型和命令。JSON-RPC 允许通知(发送到不需要响应的服务器的数据)以及将多个调用发送到服务器,这些调用可以异步应答
1
2
--> {"method": "echo", "params": ["Hello JSON-RPC"], "id": 1}
<-- {"result": "Hello JSON-RPC", "error": null, "id": 1}
-
Sun RPC:RPC 的早期实现,使用了 XDR(外部数据表示)来描述数据的序列化格式,并使用了NFS(网络文件系统)等广泛使用的网络协议
-
Java RMI: Java 远程方法调用 (Java RMI) 是一个执行远程方法调用的 Java API,相当于面向对象的 RPC
-
gRPC: Google 的开源 RPC 框架,支持众多语言
-
Dubbo: Alibaba 的开源 Java RPC框架
0x02 RPC 核心思想
1. 服务寻址
RPC 中,所有的函数都必须有自己的一个 ID,这个 ID 在所有进程中都是唯一确定的。请求和回复都需要携带这个 ID。
-
Universally Unique Identifier, UUID
-
Interface Description Language, IDL
-
AIDL, OMG IDL, WSDL, JSON-WSP
2. 序列化
语言差异、数据类型等差异使得需要数据先转化为中间格式,每种 RPC 都有自己的序列化方式,如:
-
XDR: ONC RPC 的外部数据表示
-
CDR: CORBA 的通用数据表示
-
JOSSP: Java RMI 的对象序列化流协议
-
gRPC: ProtoBuf
-
XML 序列化、JSON 序列化
3. 网络传输
RPC 不对承载的传输协议做限制,许多 RPC 都基于 TCP 协议,也可以基于 UDP 协议,XML-RPC 和 JSON-RPC 基于 HTTP协议,gRPC 基于 HTTP2 协议
这里还常常涉及到 Wire Protocol 的概念,WP 线级协议是对作为字节流通过网络发送的数据格式的描述,通常也是 API 开发的补充,可以是基于文本的(JSONWP)也可以是基于二进制的(比如 ProtoBuf)
0x03 区别于 RESTful
RESTful: 符合 REST (Representational State Transfer) 设计风格的 Web API.
区别:
-
REST 绑定与HTTP协议,RCP 的实现多样
-
REST 面向资源,RCP 面向过程
-
RCP 往往需要了解服务器端的方法才能正确使用它们,而 REST 常常能对资源进行猜测