RPC(Remote Procedure Call)
远程过程调用协议,客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。即允许像调用本地服务一样调用远程服务
- RPC框架的目的就是让远程服务调用更简单、透明,由RPC框架负责屏蔽底层的序列化、传输方式和通信细节,开发者在使用时只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程
- RPC过程调用模型
- RPC调用框架流程
- RPC框架核心组件
- Client:服务调用
- Client Stub: 存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端
- Server Stub: 接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理
- Server: 提供服务
- RPC调用流程
- Client通过本地调用的方式调用需要的服务
- Client Stub:接收到请求后负责将方法、入参等信息序列化成能够进行网络传输的消息实体
- Server Stub: 根据解码结果调用本地的服务进行相关处理
- Server: 执行具体的业务逻辑,并将结果返回给Server stub
- Server stub将返回结果序列化,并通过网络发送给消费方
- Client Stud接收到消息,并进行解码与反序列化
- Client得到最终结果
RPC框架的目标是将上面2-10步完好的封装起来,也就是把调用、编码/解码的过程给封装起来,让用户感觉上像调用本地服务一样的调用远程服务
- 一个RPC框架,考虑以下问题:
- 如何进行网络通信: 远程调用中,客户端和服务端的通讯是基于网络连接的,首先建立通信连接,通过把这个连接把请求信息的字节流传给服务端,然后再把序列化后的响应结果传回给客户端,在这个通讯过程中,所使用的协议是没有限制的,能完成传输就行
- 如何选择网络协议和如何建立连接
- 网络协议的选择:TCP、UDP、HTTP等
- 通信连接的建立:RPC所有交换的数据都在这个连接里传输,这个连接可以是按需连接,也可以是长连接
- 如何进行服务寻址: 在远程调用中,客户端和服务端需要分别维护一个【ID->函数】的映射表,ID在所有进程中都是唯一确定的,客户端在做远程过程调用时,附上这个ID,服务端通过查表,来确定客户但需要调用的函数,然后执行相应函数的代码。寻址方式的具体实现方式,可以通过注册中心,服务提供者完成后,对外暴露相应的功能并将其注册到注册中心上,客户端从注册中心寻找服务,然后调用该服务对应的方法完成远程调用
- 如何序列化和反序列化: 远程过程调用中,客户端和服务端交互时,方法的参数和结果需要通过底层的网络协议如TCP传递,由于网络协议是基于二进制的(只有二进制数据才能在网络中传输),那么这些值需要序列化成二进制的形式,通过寻址和传输将序列化的二进制发送目标服务器。目标服务器接收到数据时,需要对数据进行反序列化。序列化和反序列化的速度也会影响远程调用的效率。
- RPC网络传输协议
- 基于TCP协议实现的RPC调用,由于TCP协议处于协议栈的下层,能够灵活地对协议字段进行定制,让请求报文体积更小,减少网络开销,提高传输性能并缩短传输耗时,实现更大的吞吐量和并发数。但是需要更多关注底层复杂的细节,实现的代价更高,同时对不同平台,如安卓,iOS 等,需要重新开发出不同的工具包来进行请求发送和相应解析,工作量大,难以快速响应和满足用户需求。
- 基于HTTP协议实现的RPC则可以使用JSON和XML格式的请求或响应数据,JSON和XML作为通用的格式标准,开源解析工具已相当成熟,在其上进行二次开发会非常便捷和简单。但是由于HTTP协议是上层协议,发送包含同等内容的消息,请求中会包含很多无用的内容,所占用的字节数比使用TCP协议传输更高,因此在同等网络下,HTTP会比基于TCP协议的传输效率要低,传输耗时更长
XMLRPC
xml-rpc远程过程调用方法,它使用通过HTTP传递的XML作为载体,有了它,客户端可以在远程服务器上调用带参数的方法(服务器以URI命名)并获取结构化的数据(通过XML将调用函数封装,并使用HTTP协议作为传送机制。)
xmlrpc集合了XML-RPC服务端和客户端模块的包
- client
- server
- 工作原理
- 客户端:
Client根据指定URL找到服务端地址
- 编码请求数据
- 调用服务端上的指定服务的方法
- 接收到服务端的返回,解析响应包,拿出调用的返回结果
- 服务端
- 启动一个服务程序,注册每个能提供的服务,对每个服务对应一个Handler类
- 进入服务监听状态
- 等待Client的请求
一个简单的示例:
ServerProxy 使用其基本 URL 连接到服务器,然后直接在代理上调用方法。在代理上调用的每个方法都转换为对服务器的请求。使用 XML 格式化参数,然后通过 POST 消息将其发送到服务器。服务器解压缩 XML,并根据从客户端调用的方法名称确定要调用的函数。将参数传递给函数,然后将返回值转换回 XML,以返回给客户端。