RPC的全称是Remote Procedure Call,即远程过程调用。RPC帮助我们屏蔽网络编程细节,实现调用远程方法跟调用本地(同一个项目中的方法)一样。
RPC的作用主要体现在以下两个方面:
- 屏蔽远程调用跟本地调用的区别,使感觉调用项目内的方法
- 隐藏底层网络通信的复杂性,使更专注于业务逻辑
PRC通信流程
RPC使应用透明地完成远程调用,发起调用请求的那一方是调用方,被调用的一方是服务提供方
RPC为一个远程调用,通过网络传输数据,并且RPC常用于业务系统之间的数据交互,需要保证其可靠性,因此RPC一般默认采用TCP来传输。
网络传输数据必须是二进制数据,但请求方的出入参数都为对象,需要提前把它转换为二进制,并且要求转换算法是可逆的,该过程称为“序列化”
调用方持续地把请求参数序列化成二进制后,经过TCP传输给服务提供方,然后服务提供方再从TCP收到二进制数据,再经过反序列化得到协议中的内容,得到该请求为什么样的类型。
协议:通常分为两部分,分别为数据头和消息体。
- 数据头一般用于身份识别,包括协议标识、数据大小、请求类型、序列化类型等信息
- 消息体主要是请求的业务参数信息和扩展属性等
反序列化:根据协议格式,服务提供方从二进制数据中分割出不同的请求来,同时根据请求类型和序列化类型,把二进制的信息逆向还原成请求对象。
服务提供方再根据反序列化出来的请求对象找到对应的实现类,完成真正的方法调用,然后把执行结果序列化后,回写到对应的 TCP 通道里面。调用方获取到应答的数据包后,再反序列化成应答对象,这样调用方就完成了一次 RPC 调用。
整个流程:
由服务提供者给出业务接口声明,在调用方的程序里面,RPC 框架根据调用的服务接口提前生成动态代理实现类,并通过依赖注入等技术注入到声明了该接口的相关业务逻辑里面。该代理实现类会拦截所有的方法调用,在提供的方法处理逻辑里面完成一整套的远程调用,并把远程调用结果返回给调用方,这样调用方在调用远程方法的时候就获得了像调用本地接口一样的体验。
RPC 框架能够帮助我们解决系统拆分后的通信问题,并且能让我们像调用本地一样去调用远程方法。
RPC框架首先是通信、自定义协议(protobuf)、序列化、注册中心。我们的RPC由于C++开发的,只提供消息传输的功能,序列化和协议在应用层做的(主要是考虑不同项目的业务也有区别)。个人觉得其中最重要的就是注册中心(数据中心)实现了,这个决定了RPC所能提供扩展功能。