什么是RPC
远程过程调用(Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。 如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用,比如 Java RMI. 简单来说,通过使用 RPC,我们可以像调用方法一样快捷的与远程服务进行交互。
其中所谓的过程,就是业务处理、计算任务等等,更直白的说,就是程序,就是想调用本地方法一样调用远程的过程。
远程过程调用是一个分布式计算的客户端-服务器(Client/Server)的例子,它简单而又广受欢迎。 **远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。 **由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。
为了允许不同的客户端均能访问服务器,许多标准化的 RPC 系统应运而生了。其中大部分采用接口描述语言(Interface Description Language,IDL),方便跨平台的远程过程调用。
总而言之,RPC主要有两大重要特性:
- RPC是一种通过网络从远程计算机程序上请求服务,不需要了解底层网络技术的协议。
- RPC主要作用是不同的服务间方法调用就像本地调用一样便捷。
架构
可以看出RPC采用客户端/服务端的模式,通过request-response消息模式实现,我们所熟知的 HTTP协议也是一个简单的请求响应协议
这里的Stub,我们通常称之为存根,用来转换RPC过程中传递的参数:
-
**客户端存根(Client Stub):**存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。
-
**服务端存根(Server Stub):**接收客户端发送过来的消息,将消息解包,并调用本地的方法。
服务的调用过程为:
- client调用client stub,这是一次本地过程调用
- client stub将参数打包成一个消息,然后发送这个消息。打包过程也叫做 marshalling(序列化)
- client所在的系统将消息发送给server
- server的的系统将收到的包传给server stub
- server stub解包得到参数。 解包也被称作 unmarshalling(反序列化)
- 最后server stub调用服务过程. 返回结果按照相反的步骤传给client
可以看出来 RPC 的客户端和服务器端是高度耦合的
RPC vs RESTful
RPC 的消息传输可以通过 TCP、UDP 或者 HTTP等,所以有时候我们称之为 RPC over TCP、 RPC over HTTP。RPC 通过 HTTP 传输消息的时候和 RESTful的架构是类似的,但是也有不同。
首先我们比较 RPC over HTTP 和 RESTful。
**首先 RPC 的客户端和服务器端是紧耦合的,客户端需要知道调用的过程的名字,过程的参数以及它们的类型、顺序等。**一旦服务器更改了过程的实现, 客户端的实现很容易出问题。RESTful基于 http的语义操作资源,参数的顺序一般没有关系,也很容易的通过代理转换链接和资源位置,从这一点上来说,RESTful 更灵活。
其次,它们操作的对象不一样。 RPC 操作的是方法和过程,它要操作的是方法对象。 RESTful 操作的是资源(resource),而不是方法。
第三,RESTful执行的是对资源的操作,增加、查找、修改和删除等,主要是CURD,所以如果你要实现一个特定目的的操作,比如为名字姓张的学生的数学成绩都加上10这样的操作, RESTful的API设计起来就不是那么直观或者有意义。在这种情况下, RPC的实现更有意义,它可以实现一个 Student.Increment(Name, Score) 的方法供客户端调用。
我们再来比较一下 RPC over TCP 和 RESTful。 如果我们直接使用socket实现 RPC,除了上面的不同外,我们可以获得性能上的优势。
RPC over TCP可以通过长连接减少连接的建立所产生的花费,在调用次数非常巨大的时候(这是目前互联网公司经常遇到的情况,大并发的情况下),这个花费影响是非常巨大的。当然 RESTful 也可以通过 keep-alive 实现长连接, 但是它最大的一个问题是它的request-response模型是阻塞的 (http1.0和 http1.1, http 2.0没这个问题), 发送一个请求后只有等到response返回才能发送第二个请求 (有些http server实现了pipeling的功能,但不是标配), RPC的实现没有这个限制
在当今用户和资源都是大数据大并发的趋势下,一个大规模的公司不可能使用一个单体程序提供所有的功能,微服务的架构模式越来越多的被应用到产品的设计和开发中, 服务和服务之间的通讯也越发的重要, 所以 RPC 不失是一个解决服务之间通讯的好办法.
总而言之,RESTFUL和RPC有以下区别:
- RPC 的客户端和服务器端是紧耦合的,Restful与之相比更灵活
- 操作对象不同,RPC主要操作方法和过程,Restful操作资源
- RESTful执行的是对资源的操作,主要是CURD,Restful与之相比起来就显得不是那么的直观
- RPC可以通过长连接减少连接的建立所产生的花费,Restful虽然也可以进行长链接,但是由于请求响应的模型的阻塞机制,导致效率不是很高。
RPC和Socket
在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据 socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。 即socket是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。 Socket()函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。
RPC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用).
为什么要有RPC?
- 服务化:
- 微服务化,跨平台的服务之间远程调用;
- 分布式系统架构:
- 分布式服务跨机器进行远程调用;
- 服务可重用:
- 开发一个公共能力服务,供多个服务远程调用。
- 系统间交互调用:
- 两台服务器A、B,服务器A上的应用a需要调用服务器B上的应用b提供的方法,而应用a和应用b不在一个内存空间,不能直接调用,此时,需要通过网络传输来表达需要调用的语义及传输调用的数据。
RPC核心概念术语
- client, 客户端
- server,服务端
- calls,请求
- replier,响应
- services,一个网络服务由一个或者多个远程程序集构成
- programs,一个远程程序实现一个或多个远程过程
- procedures,过程、过程的参数、结果在程序协议说明书中定义说明
- version,为兼容程序协议变更,一个服务端可能支持多个版本的远程程序
使用场景
大型网站:内部涉及多个子系统,服务、接口较多。注册发现机制:如Nacos、Dubbo等,一般都有注册中心,服务有多个实例,调用方调用的哪个实例无感知。- 安全性`:不暴露资源。
服务化治理:微服务架构、分布式架构。