RPC的基本概念 | 青训营笔记

98 阅读5分钟

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

今天学习一下 RPC 框架,在学习之前我们首先要了解 RPC 的基本概念。在之前我也学习了一些关于RPC的概念,但是没有像今天的课程这么介绍过。通过今天的学习让我了解到 RPC 框架的意义以及以后如何去应用到实际业务中。

1 基本概念

1.1 本地函数调用

fun main() {
    var a = 2
    var b = 3
    result := calculate(a, b)
    fmt.Println(result)
    return
}
func calculate(x, y int) {
    z := x + y
    return z
}

步骤:

  1. 将 a 和 b 的值压栈
  2. 通过函数指针找到 calculate 函数,进入函数取出栈中的值 2 和 3 ,将其赋予 x 和 y
  3. 计算 x + y,并将结果存在 z
  4. 将 z 的值压栈,然后从 calculate 返回
  5. 从栈中取出 z 返回值,并赋值给 result

在实际中:编译器经常会做优化,对于参数和返回值少的情况会直接将其存放在寄存器,而不需要压栈弹栈的过程,甚至不需要调用 call ,而直接做 inline 操作。

1.2 远程函数调用(RPC-Remote Procedure Calls)

在这里插入图片描述

我们应该如何告诉支付服务,我们要调用这个函数,而不是退款或者充值?

在本地调用中,函数体是直接通过函数指针来指定的,我们调用哪个方法,编译器就自动帮我们调用它相应的函数指针。但在远程函数调用中,函数指针是不行的。因为两个进程的地址空间是完全不一样的,所以函数都有自己的一个ID,以及 ID 和函数的对照关系表,通过 ID 找到对应的函数并执行

客户端如何把参数值传给远程的函数呢?

在本地调用中,我们只需要把参数压到栈里,然后让函数自己去栈里读就行。但是在远程过程调用时,客户端和服务端是不同的进程,不能通过内存来传递参数。此时需要客户端把参数先转给一个字节流,传给服务端后,再把字节流转成自己能读取的格式。

此时我们需要明白:远程调用往往用在网络中,如何保证在网络上高效稳定地传输数据?

通过上述过程,我们明白了:

RPC 需要解决的问题

  1. 函数映射
  2. 数据转换成字节流
  3. 网络传输

1.3 RPC 概念模型

这是 RPC的概念模型,来源于 1984 年 Nelson 发表的论文《Implementing Remote Procedure Calls》,其中提出了 RPC 的过程由 5 个模型组成:User、User-Stub、RPC-Runtime、Server-Stub、Server

在这里插入图片描述

1.4 一次 RPC 的完整过程

在这里插入图片描述

相比本地函数调用,远程调用的话不知道对方由什么方法,以及参数是什么。所以我们需要有一种方式来描述或表明自己有哪些方法以及方法的参数。这个描述文件就是IDL文件。

刚才服务双方是通过约定的规范进行远程调用,双方都依赖于同一份IDL文件,需要通过工具来生成对应的生成文件,具体调用的时候用户代码需要依赖生成代码。所以可以把用户代码和生成代码看成一个整体。

编码只是解决了跨语言的数据交换格式,但是如何进行通讯:这时需要制订通讯协议,以及数据传输。这里就是transfer要做的事。

概念

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

1.5 RPC 的好处

  1. 单一职责。有利于分工协作和运维开发。(采用不同语言开发,部署以及运维都是独立的)
  2. 可扩展性强,资源使用率更优。压力过大的时候可以独立扩充资源,底层基础服务可以复用,节省资源。
  3. 故障隔离,服务的整体可靠性更高。某个模块发生故障不会影响到整体。

在这里插入图片描述

1.6 RPC 带来的问题

RPC有好处也会带来问题

  1. 服务宕机,对方应该如何处理?
  2. 在调用过程中发生网络异常,如何保证消息的可达性?
  3. 请求量突增导致服务无法及时处理,有哪些应对措施?

总结

  1. 本地函数调用和 RPC 调用的区别:函数映射、数据转成字节流、网络传输
  2. RPC 的概念模型:User、User-Stub、RPC-Runtime、Server-Stub、Server
  3. RPC 带来好处的同时也带来了新的问题。这些问题将由 RPC 框架来解决。