RPC框架理论笔记 | 青训营笔记

117 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天

今天和大家分享一下 RPC 框架的基本概念和分层设计理论。

Rpc框架

RPC 基本概念

引例(函数调用):

func main() {
    var a = 3
    var b = 3
    sum := add(a, b)
}
func add (a, b int) int {
    returm a + b
}

上述的本地函数的调用,直接通过主函数中调用工具函数就行了。

然而我们 RPC( Remote Procedure Calls )是远程调用函数,所以相较于上面的本地函数调用,我们需要解决以下几个问题:

  1. 函数映射问题:如何告诉一个服务如何正确的调用另一个服务的指定函数。
  2. 数据转换成字节流:我们的参数和返回数据都需要转换成字节流在两个服务之间进行通讯(因为默认两个服务在不同的内存和进程,不能通过内存共享,数据入栈等方式进行数据直接传递)。
  3. 网络传输:对于两个服务来说,传输数据往往是通过网络进行传递的。

现代的 RPC 框架,在不断探索之中已经很好的解决了上面的问题,在讨论现代框架之前,我们先了解一些相关的概念

  1. IDL :IDL 通过一种中立的方式来描述接口,使得在不同平台上运行的对象和不同语言编写的程序可以相互通信;
  2. 生成代码:通过编译器工具把 IDL 文件转换成语言对应的静态库;
  3. 编解码:从内从中表示到字节序列的转换成为编码,反之为解码,也常叫做序列化和反序列化;
  4. 通信协议:规范了数据在网络中的传输内容和格式。出必须的请求/相应书之外,通常还包括额外的元数据;
  5. 网络传输:通常基于成熟的网络库走 TCP/UDP 传输。

RPC 分层设计

首先,RPC 一般会有两个对称的端,被称为调用端( Client端 )和非调用端( Server端 ),服务实现写在非调用端中,而调用段则用来使用服务。

接下来的分层设计中,不强调是哪一个端,默认是对称设计的。

  1. 编解码层

    在编解码层,从上到下分别为:业务逻辑层( Code层,用户编写 );生成代码( IDL生成 );编解码层;协议层;网络通讯层(用来在 Client 和 Server 端通讯 )

    框架的编解码层是用来定义 RPC 框架的数据格式的。该数据格式应该具有前后兼容性通用性性能三个方面考虑。现代框架中,一般会使用编程语言内建的格式或者比较通用的二进制编码(如 BinaryProtocol,Protobuf 等 )。

    以 BinaryProtocol 为例,其为 Thrift 的 IDL 文件生成, 书写 IDL 时,数据结构由三部分组成,分别为指定类型的 Tag,指定长度的 Length,指定编码值的 Value。进而生成字节流(即 BinaryProtocol )。

    将数据生成字节流后,我们需要为其加入一些元数据,补位,结束符等一些标识,好用来进行网络通讯。这一步就是协议层进行的。

    RPC 的网络通讯使用 Sockets API 为底层的网络库进行在接收端和被接收端之间通讯: