Random Thoughts
Recent content on Random Thoughts
马上订阅 Random Thoughts RSS 更新: https://blog.joway.io/index.xml
RPC 漫谈:序列化问题
何为序列
对于计算机而言,一切数据皆为二进制序列。但编程人员为了以人类可读可控的形式处理这些二进制数据,于是发明了数据类型和结构的概念,数据类型用以标注一段二进制数据的解析方式,数据结构用以标注多段(连续/不连续)二进制数据的组织方式。
例如以下程序结构体:
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 代码内容一般分为两块:
- 类型结构体生成(即目标语言的 Struct[Golang]/Class[Java] )
- 序列化/反序列化代码生成(将二进制流与目标语言结构体相转换)
下面是一段 Thrif...
剩余内容已隐藏