深入浅出RPC框架 | 青训营

26 阅读4分钟

一、基础概念

1、本地函数调用

func 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操作。

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

image.png

函数映射:怎样告诉支付服务我们要调用付款这个函数,而不是退款或充值?

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

客户端如何将参数值传给远程函数?

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

3、RPC概念模型

image.png

4、一次RPC的完整过程

  • IDL(Interface description language)文件

通过一种中立的方式来描述接口,使得在不同平台上运行的对象和不同语言编写的程序可以相互通信。

  • 生成代码

通过编译器工具把IDL文件转换成语言对应的静态库。

  • 编解码

从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化。

  • 通信协议

规范了数据在网络中的传输内容和格式,除必须的请求/相应数据外,通常还包含额外的元数据

  • 网络传输

通常基于成熟的网络库走TCP/UDP传输

image.png

5、RPC的好处

(1)单一职责,有利于分工协作和运维开发

(2)可扩展性强,资源使用率更优

(3)故障隔离,服务的整体可靠性更高

image.png

6、RPC带来的问题

(1) 服务宕机,对方如何处理?

(2)在调用过程中发生网络异常,如何保证消息的可达性?

(3)请求量突增导致服务无法及时处理,有哪些应对措施?

二、分层设计

1、分层设计-以Apache Thrift为例

image.png

2、编解码层-生成代码

image.png

3、编解码层-数据格式

  • 语言特定的格式

许多编程语言都内建了将内存对象编码为字节序列的支持,例如Java有java.io.Serializable

  • 文本格式

JSON、XML、CSV等文本格式,具有人类可读性

  • 二进制编码

具备跨语言和高性能等优点,常见有Thrift的BinaryProtocol、Protobuf等

4、编解码层-二进制编码

TLV编码

  • Tag:便签,可以理解为类型
  • Length:长度
  • Value:值,Value也可以是TLV结构

image.png

5、编解码层-选型

  • 兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
  • 通用性:支持跨平台、跨语言
  • 性能:从空间和时间两个维度考虑,也就是编码后数据大小和编码耗费时长

6、协议层

(1)概念

image.png

(2)协议构造

  • LENGTH:数据包大小,不包含自身
  • HEARER MAGIC:标识版本信息,协议解析时快速校验
  • SEQUENCE NUMBER:表示数据包的seqID,可用于多路复用,单连接内递增
  • HEADER SIZE:头部长度,从第14个字节开始计算一直到PAYLOAD前
  • PROTOCOL ID:编解码方式,有Binary和Compact两种
  • TRANSFORM ID:压缩方式,如zlib和snappy
  • INFO ID:传递一些定制的meta信息
  • PAYLOAD:消息体

image.png

(3)协议解析

image.png

5、网络通信层

(1)Sockets API

image.png

(2)网络库

  • 提供易用API

封装底层Socket API 连接管理和事件分发

  • 功能

协议支持:tcp、udp和uds等 优雅退出、异常处理等

  • 性能

应用层buffer减少copy

高性能定时器、对象池等