Random Thoughts

Recent content on Random Thoughts

马上订阅 Random Thoughts RSS 更新: https://blog.joway.io/index.xml

RPC 漫谈:序列化问题

2021年4月30日 08:00

何为序列

对于计算机而言,一切数据皆为二进制序列。但编程人员为了以人类可读可控的形式处理这些二进制数据,于是发明了数据类型和结构的概念,数据类型用以标注一段二进制数据的解析方式,数据结构用以标注多段(连续/不连续)二进制数据的组织方式。

例如以下程序结构体:

type User struct {
 Name string
 Email string
}

Name 和 Email 分别表示两块独立(或连续,或不连续)的内存空间(数据),结构体变量本身也有一个内存地址。

在单进程中,我们可以通过分享该结构体地址来交换数据。但如果要将该数据通过网络传输给其他机器的进程,我们需要现将该 User 对象中不同的内存空间,编码成一段连续二进制表示,此即为「序列化」。而对端机器收到了该二进制流以后,还需要能够认出该数据为 User 对象,解析为程序内部表示,此即为「反序列化」。

序列化和反序列化,就是将同一份数据,在人的视角和机器的视角之间相互转换。

序列化过程

定义接口描述(IDL)

为了传递数据描述信息,同时也为了多人协作的规范,我们一般会将描述信息定义在一个由 IDL(Interface Description Languages) 编写的定义文件中,例如下面这个 Protobuf 的 IDL 定义:

message User {
 string name = 1;
 string email = 2;
}

生成 Stub 代码

无论使用什么样的序列化方法,最终的目的是要变成程序中里的一个对象,虽然序列化方法往往是语言无关的,但这段将内存空间与程序内部表示(如 struct/class)相绑定的过程却是语言相关的,所以很多序列化库才会需要提供对应的编译器,将 IDL 文件编译成目标语言的 Stub 代码。

Stub 代码内容一般分为两块:

  1. 类型结构体生成(即目标语言的 Struct[Golang]/Class[Java] )
  2. 序列化/反序列化代码生成(将二进制流与目标语言结构体相转换)

下面是一段 Thrif...

剩余内容已隐藏

查看完整文章以阅读更多