这周末我们来看看数据交换格式:JSON(BSON)、Protocol Buffers和MessagePack。每当客户端和服务器、后端服务与服务之间通信时候,都会交换数据,如何将本机程序内存中的数据交给远端程序使用,同时不受语言、架构等限制就成为了一个问题。我们将对象转化为可以存储或传输的形式这个过程称为序列化,而其逆向过程称为反序列化。
JSON
这或许是大家最熟悉的一种格式了,JSON格式广泛用于C/S架构中通信,其具有良好的可读性,一段样例JSON如下:
|
|
JSON可以传递数字、布尔、数组、字符串、对象、空类型的数据,但是对于二进制数据不太方便,除非你进行编码(如Base64)或者转换成数组。由于是字符串格式,JSON可读性较好,但是处理速度并不理想。
顺带,JSON发展于2000年初。
BSON
BSON目前主要运用于MongoDB中,BSON的含义即“二进制JSON”,相较于JSON,BSON使用二进制格式来进行编码,参考自JSON and BSON,一个BSON和JSON的样例如下:
|
|
相较于JSON,BSON通过二进制表示了数据的类型和长度,这加快了遍历速度。同时BSON支持了JSON不支持的日期和二进制数据。
Protocol Buffers
Protocol Buffer是2008年由Google开发的序列化协议,其设计目标就是简单和性能。Protocol Buffer需要双方约定好消息的定义(.proto
文件),一个示例如下:
|
|
假如a的值为150,你会得到如下的序列化结果:
|
|
我们怎么来看呢?对于第一个字节代表Tag和类型,前5位代表Tag即上面的1,之后000三个bit代表其类型是VARINT,作为整数、无符号整数、布尔、枚举类型的统称。
|
|
对于类型和编码更多详细内容可以阅读官方文档:Encoding。
我们可以发现ProtoBuf是用tag来表示数据的Key的,和其真正名称无关。ProtoBuf是二进制格式不具有可读性,但是传输开销和(反)序列化开销较小。
MessagePack
MessagePack目前最新的版本是2009年发布的0.3.3版本,MessagePack专注于紧凑和简单。一个JSON到MessagePack的样例如下:
|
|
对于更加详细的编码规则可以参考spec。MessagePack对应于JSON,但是支持二进制数组等JSON本不支持的格式。由于是二进制格式,其仍然可读性不佳,但是性能较JSON好。