声明:转载自搜狐-科技-运维前沿
RPC简介
RPC(Remote Procedure Call,即远程过程调用)是建立在Socket之上的,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用)。也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。对于RPC架构来说,应用越底层,代码越复杂、灵活性越高、效率越高;应用越上层,抽象封装的越好、代码越简单、效率越差。
通过RPC,我们可以充分利用非共享内存的多处理器环境(例如通过局域网连接的多台应用服务器),这样可以简便地将你的应用分布在多台应用服务器上,应用程序就像运行在一个多处理器的计算机上一样。我们可以方便的实现过程代码共享,提高系统资源的利用率,也可以将以大量数值处理的操作放在处理能力较强的系统上运行,从而减轻前端机的负担。
RPC作为普遍的C/S开发方法,开发效率高效、可靠。但RPC方法的基本原则是:以模块调用的简单性忽略通讯的具体细节,以便程序员不用关心C/S之间的通讯协议,集中精力实现应用过程。这就决定了 RPC生成的通讯包不可能对每种应用都有最恰当的处理办法,与Socket方法相比,传输相同的有效数据,RPC占用更多的网络带宽。RPC是在Socket的基础上实现的,它比socket需要更多的网络和系统资源。
RPC架构的作用
RPC 的主要目标是让构建分布式计算(应用)更容易、透明,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用。RPC框架负责屏蔽底层的传输方式(TCP或者UDP)、序列化方式(XML/JSON/二进制)和通信细节。开发人员在使用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。
1、从通信协议的层面,大致可以分为:
(1)基于HTTP协议的(例如基于文本的SOAP(XML)、REST(JSON)、基于二进制Hessian(Binary));
(2)基于TCP协议的(通常会借助Mina、Netty等高性能网络框架)。
2、只有二进制数据才能在网络中传输,序列化和反序列化的定义是:
(1)将对象转换成二进制流的过程叫做序列化;
(2)将二进制流转换成对象的过程叫做反序列化。
3、 RPC架构分为三部分:
(1)、服务提供者(RPC Server),运行在服务器端,提供服务接口定义与服务实现类。
(2)、服务中心(Registry),运行在服务器端,负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。
(3)、服务消费者(RPC Client),运行在客户端,通过远程代理对象调用远程服务。
服务提供者启动后主动向服务(注册)中心注册机器ip、端口以及提供的服务列表; 服务消费者启动时向服务(注册)中心获取服务提供方地址列表,可实现软负载均衡和Failover。
RPC调用流程
简单来说一个RPC架构里包含如下4个组件:
1、 客户端(RPC Client):服务调用方
2、 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数打包成网络消息,再通过网络发送给服务方
3、 服务端存根(Server Stub):接受客户端发送过来的消息并解包,再调用本地服务
4、 服务端(RPC Server):真正的服务提供者。
RPC采用C/S模式,请求程序就是一个客户端应用,而服务提供者就是一个服务器。首先,服务消费者(RPC客户端应用)调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务提供方(RPC服务器端),进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,调用服务端方法对调用请求进行计算而得到计算结果,并发送答复信息,然后等待下一个调用信息;最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
一次完整的RPC调用流程如下:
1)、服务消费方(Client)调用以本地调用方式调用服务;
2)、Client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)、Client stub找到服务地址,通过Socket将消息发送到服务端;
4)、Server stub收到消息后进行解码;
5)、Server stub根据解码结果调用服务端本地的服务;
6)、本地服务执行并将结果返回给Server stub;
7)、Server stub将返回结果打包成消息;
8)、Server stub通过Socket将消息发送至客户端;
9)、Client stub接收到消息,并进行解码;
10)、服务消费方(RPC Client)得到最终的服务调用结果。
RPC框架的目标就是要2~9这些步骤都封装起来,让用户对这些细节透明。
当我们在建立RPC服务以后,客户端的调用参数通过底层的RPC传输通道,可以是UDP,也可以是TCP,并根据传输前所提供的目的地址及RPC上层应用程序号转至相应的RPC应用程序服务端,且此时的客户端处于等待状态,直至收到应答或Time Out超时信号。当服务器端获得请求消息,则会根据注册RPC时告诉RPC系统的例程入口地址,执行相应的操作,并将结果返回至客户端。
当一次RPC调用结束后,相应线程发送相应的信号,客户端程序才会继续运行。在这个过程中,一个远程过程是有三个要素来唯一确定的:程序号、版本号和过程号。
程序号是用来区别一组相关的并且具有唯一过程好的远程过程。一个程序可以有一个或几个不同的版本,而每个版本的程序都包含一系列能被远程调用的过程,通过版本的引入,使得不同版本下的RPC能同时提供服务。每个版本都包含有许多可供远程调用的过程,每个过程则有其唯一标示的过程号。
4
RPC核心技术点和应用构架
1. 核心技术点
(1)、服务提供者需要以某种形式提供服务调用相关的信息,包括但不限于服务接口定义、数据结构、或者中间态的服务定义文件。例如Facebook的 Thrift的IDL文件,Web service的WSDL文件;服务的调用者需要通过一定的场景获取远程服务调用相关的信息。
(2)、远程代理对象:服务调用者用的服务实际是远程服务的本地代理。说白了就是通过动态代理来实现。
(3)、通信:RPC框架与具体的协议无关。
(4)、序列化:毕竟是远程通信,需要将对象转化成二进制流进行传输。不同的RPC框架应用的场景不同,在序列化上也会采取不同的技术。
2. 常见RPC技术和框架
(1)、应用级的服务框架:阿里的Dubbo/Dubbox、Google GRPC、Spring Boot/Spring Cloud。
(2)、远程通信协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
(3)、通信框架:MINA和Netty。