1.6 初识序列化/反序列化

1.6.1 技术背景

互联网的迅猛发展受益于网络通信技术的成熟和稳定。网络通信协议是机器双方共同约定的协议。在应用层看到的是结构体、对象,但是在网络协议里,机器之间传输的都是二进制流。网络编程中,需要定义应用层协议。最原始的应用层协议是字节数组,在Java语言里以byte[]体现,在C语言里以char[]体现。不管是Java语言还是C语言,开发人员都需要知道字节数组里每个字节的含义才能保证数据写入和读取的正确性。这对开发人员来说,是非常严苛且低效的。

如何将程序中的结构体、对象等结构化内存对象转换为扁平的二进制流?如何将二进制流还原为结构化内存对象?为了解决这些问题,序列化/反序列化技术应运而生。

1.6.2 技术特征

在众多序列化/反序列化技术方案中,如何根据业务需求选择合适的方案,是经常要面临的问题。在分布式、大数据系统设计里,问题表现得尤为突出。恰当的序列化协议不仅可以提高系统的通用性、健壮性、高效性,而且会让系统更加易于调试、便于扩展。一般来说,会从以下5个维度来综合考量一个技术方案是否合适。

成熟度:社区是否成熟,是否能及时跟进Issue并解决Bug。

跨语言能力:跨语言能力是序列化/反序列化技术的核心指标之一,根据项目实际需求来决定是否需要跨语言。

易用性:易用性决定了开发者是不是需要花很多时间去学习,门槛是不是很高,接口是不是容易理解和使用。

扩展性:扩展性表现为随着业务需求变化需要增减字段。字段变化的过程中,不会对现有系统的数据存储、数据访问造成影响,具有向后兼容性。扩展性也是序列化/反序列化技术的核心指标之一。

性能:性能包括存储空间开销和时间开销。存储空间由编码方案决定,序列化/反序列化的过程消耗的时间称为时间开销。性能也是序列化/反序列化技术的核心指标之一。

1.6.3 IDL序列化引擎

一般来说,序列化/反序列化分为IDL(Interface Description Language,接口描述语言)和非IDL两类。非IDL技术方案包含JSON、XML等,提供构造和解析的工具包即可使用,不需要做代码生成的工作。IDL技术方案包含Thrift、Protocol Buffer、Avro等,有比较完整的规约和框架实现,一般包含如下通用的关键组件,如图1-2所示。

img

图1-2 IDL工作原理

IDL描述文件:比如,Thrift是以thrift为后缀的文件,Protocol Buffer是以proto为后缀的文件。

IDL文件编译器:根据IDL文件生成具有序列化/反序列化功能的代码文件。例如,Thrift通过thrift命令行指定编程语言类型来生成代码文件,Protocol Buffer根据protoc命令行生成代码文件。

Stub/Skeleton代码:在客户(Client)端,一般称为Stub代码。在服务器(Server)端,一般称为Skeleton代码。