RPC是什么?
RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。为什么要用RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数。
RPC调用的流程
要让网络通信细节对使用者透明,我们自然需要对通信细节进行封装,我们先看下一个RPC调用的流程:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC协议
RPC的协议有很多,比如最早的CORBA,Java RMI,Web Service的RPC风格,Hessian,Thrift,甚至Rest API。
XML-RPC,SOAP,WebService
- 冗余数据太多,处理速度太慢。
- RPC 风格的 Web Service 跨语言性不佳,而 Document 风格的 Web Service 又太过难用。
- Web Service 没有解决用户的真正问题,只是把一个问题变成了另一个问题。
- Web Service 的规范太过复杂,以至于在 .NET 和 Java 平台以外没有真正好用的实现,甚至没有可用的实现。
- 跨语言跨平台只是 Web Service 的一个口号,虽然很多人迷信这一点,但事实上它并没有真正实现。
PHPRPC
- 基于 PHP 内置的序列化格式,在跨语言的类型映射上存在硬伤。
- 通讯上依赖于 HTTP 协议,没有其它底层通讯方式的选择。
- 内置的加密传输既是特点,也是缺点。
- 虽然比基于 XML 的 RPC 速度快,但还不是足够快。
Hessian
- 二进制的数据格式完全不具有可读性。
- 官方只提供了两个半语言的实现(Java,ActionScript 和不怎么完美的 Python 实现),其它语言的第三方实现良莠不齐。
- 支持的语言不够多,对 Web 前端的 JavaScript 完全无视。
- 虽然是动态 RPC,但动态性仍然欠佳。
- 虽然比基于 XML 的 RPC 速度快,但还不是足够快。
JSON-RPC
- JSON 具有文本可读性,且比 XML 更简洁。
- JSON 受 JavaScript 语言子集的限制,可表示的数据类型不够多。
- JSON 格式无法表示数据内的自引用,互引用和循环引用。
- 某些语言具有多种版本的实现,但在类型影射上没有统一标准,存在兼容性问题。
- JSON-RPC 虽然有规范,但是却没有统一的实现。在不同语言中的各自实现存在兼容性问题,无法真正互通。
Microsoft WCF,WebAPI
- 它们是微软对已有技术的一个 .NET 平台上的统一封装,是对 .NET Remoting、WebService 和基于 JSON 、XML 等数据格式的 REST 风格的服务等技术的一个整合。
- 虽然号称可以在 .NET 平台以外来调用它的这些服务,但实际上跟在 .NET 平台内调用完全是两码事。它没有提供任何在其他平台的语言中可以使用的任何工具。
ZeroC Ice,Thrift,GRPC
- 初代 RPC 技术的跨语言面向对象的回归。
- 仍然需要通过中间语言来编写类型和接口定义。
- 仍然需要用代码生成器来将中间语言编写的类型和接口定义翻译成你所使用的编程语言的客户端和服务器端的占位程序(stub)。
- 你必须要基于生成的服务器代码来单独编写服务,而不能将已有代码直接作为服务发布。
- 你必须要用生成的客户端代码来调用服务,而没有其它更灵活的方式。
- 如果你的中间代码做了修改,以上所有步骤你都要至少重复一遍。
Hprose
- 无侵入式设计,不需要单独定义类型,不需要单独编写服务,已有代码可以直接发布为服务。
- 具有丰富的数据类型和完美的跨语言类型映射,支持自引用,互引用和循环引用数据。
- 支持众多传输方式,如 HTTP、TCP、Websocket 等。
- 客户端具有更灵活的调用方式,支持同步调用,异步调用,动态参数,可变参数,引用参数传递,多结果返回(Golang)等语言特征,Hprose 2.0 甚至支持推送。
- 具有良好的可扩展性,可以通过过滤器和中间件实现加密、压缩、缓存、代理等各种功能性扩展。
- 兼容的无差别跨语言调用
- 支持更多的常用语言和平台
- 支持浏览器端的跨域调用
- 没有中间语言,无需学习成本
- 性能卓越,使用简单