因为涉及到分布式集群之间的通信,所以来学习了下 ProtoBuf,为什么选择 ProtoBuf 呢?主要还是因为相对于 json , xml 来说,ProtoBuf 传输效率更快,故需要了解下它的编码设计。
首先,每一个 message 进行编码,其结果由一个个字段组成,每个字段可划分为 Tag - [Length] - Value,如下图所示:
Tag 由 field_number 和 wire_type 两个部分组成:
- field_number: message 定义字段时指定的字段编号
- wire_type: ProtoBuf 编码类型,根据这个类型选择不同的 Value 编码方案。
3 bit 的 wire_type 最多可以表达 8 种编码类型,目前 ProtoBuf 已经定义了 6 种,如上图所示,那么 makeTag 的代码就非常简单明了。
static int makeTag(int fieldNumber , int wireType){
return (fieldNumber << 3) | wireType
}
1. length 可有可无,主要针对于字符串的时候就会加上 length 方便判断 value 长度。
2. Varints 编码,主要是牺牲第一个比特位,来判断数据是否结束。
3. ZigZag 编码,主要是针对于出现负数的时候,负数的补码所占用的字节过多,采用了负数向正数映射的方式。
推荐&参考阅读:
[深入 ProtoBuf - 简介](深入 ProtoBuf - 编码 - 简书)
[深入 ProtoBuf - 编码](深入 ProtoBuf - 编码 - 简书)