RPC框架的职责是:让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务
RPC
标签(空格分隔): 微服务
参考花了一个星期,我终于把RPC框架整明白了整理记录。
RPC是一种技术思想而非一种规范或协议。
现状
微服务大行其道,微服务之间的通信怎么办呢?
随着巨石应用的拆分,多个微服务共同完成应用功能,许多相似或一样的功能代码被抽离出来作为底层服务,它们之间需要一种通信方式。
RPC,Remote Procedure Call,远程过程调用,它是一种通过网络从远程计算机上请求服务,而不需要理解底层网络技术的思想。
通过RPC,可以像调用本地方法一样调用远程服务,不同的微服务也可以根据不同的场景选择最适合的开发语言和技术架构。
RPC
完整的RPC架构图镇楼
在一个典型的RPC的使用场景中,包含了服务注册、服务发现、负载均衡、容错、网络传输、序列化等组件。
RPC协议部分包括序列化、反序列化、协议编码解码和网络传输。
核心功能
RPC 的核心功能是指实现一个 RPC 最重要的功能模块
一个RPC的核心功能主要有5个部分组成,分别是:客户端、客户端Stub、网络传输模块、服务端Stub、服务端
其中:
- 客户端(client): 服务调用方
- 客户端存根(client stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络信息,再通过网络传输层发送给服务端。
- 服务端存根(server stub):接受客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理。
- 服务端(server):服务的真正提供者。
- 网络传输层(Network Service): 底层传输,可以是TCP或HTTP2
核心功能实现
RPC的核心功能主要由5个模块组成,主要技术点是:
- 服务寻址
- 数据流的序列化和反序列化
- 网络传输
服务寻址
本地调用方法的时候,可以通过函数指针来指定。
远程调用方法的时候,需要通过一种映射机制来找到服务端方法。
服务寻址可以使用 Call ID 映射。在本地调用中,函数体是直接通过函数指针来指定的,但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。
所以在 RPC 中,所有的函数都必须有自己的一个 ID。这个 ID 在所有进程中都是唯一确定的。
客户端在做远程过程调用时,必须附上这个 ID。然后我们还需要在客户端和服务端分别维护一个函数和Call ID的对应表。
当客户端需要进行远程调用时,它就查一下这个表,找出相应的 Call ID,然后把它传给服务端,服务端也通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。
序列化和反序列化
客户端和服务端不在一个进程内,两者的数据交换只能通过字节流,而在网络传输中,是以二进制数据的形式呈现的。
将对象转换成二进制流的过程叫做序列化
将二进制流转换成对象的过程叫做反序列化
客户端发起请求,需要序列化数据,接受返回结果需要反序列化数据
服务端接受请求,需要反序列化数据,发送返回结果需要序列化数据
网络传输
远程调用往往用在网络上,客户端和服务端是通过网络连接的。
因此需要一个网络传输层来传递客户端和服务端之间的数据。
目前RPC框架传输层协议大多使用TCP协议,也可以使用UDP和HTTP、HTTP2
基于 TCP 的协议实现的 RPC 调用,由于 TCP 协议处于协议栈的下层,能够更加灵活地对协议字段进行定制,减少网络开销,提高性能,实现更大的吞吐量和并发数。
基于 HTTP 协议实现的 RPC 则可以使用 JSON 和 XML 格式的请求或响应数据。但是由于 HTTP 协议是上层协议,发送包含同等内容的信息,使用 HTTP 协议传输所占用的字节数会比使用 TCP 协议传输所占用的字节数更高。
因此在同等网络下,通过 HTTP 协议传输相同内容,效率会比基于 TCP 协议的数据效率要低,信息传输所占用的时间也会更长,当然压缩数据,能够缩小这一差距。
结论
- RPC框架是架构微服务化的首要基础组件,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节
- RPC框架的职责是:让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务