最后更新:2022-08-02 22:53:51 手机定位技术交流文章
Thrift 是 Facebook 开源的一个高性能,轻量级 RPC 服务框架,是一套全栈式的 RPC 解决方案,包含序列化与服务通信能力,并支持跨平台/跨语言。整体架构如图所示:

Thrift软件堆是明确定义的,每个组件层是松散耦合的,相互连接的,并且可以根据业务场景灵活地结合,如图所示:

储蓄本身是一个相对大的话题,这篇文章不包括所有内容,只是其中所包含的序列协议。

编码简图

编码具体内容
编码含义
消息头
msg_type:消息类型,包含四个类型
呼叫: 客户端消息. 呼叫远程方法,并期望对方发送答复.
OneWay:客户端消息。调用远程方法,不期待响应。
答复:服务侧消息。
Exception:服务端消息。异常响应。
msg_seq_id:消息序号。客户端使用消息序号来处理响应的失序到达,实现请求和响应的匹配。服务端不需要检查该序列号,也不能对序列号有任何的逻辑依赖,只需要响应的时候将其原样返回即可。
消息体
消息体分为两个编码模式:
定长类型 -> T-V 模式,即:字段类型 + 序号 + 字段值
变长类型 -> T-L-V 模式,即:字段类型 + 序号 + 字段长度 + 字段值
field_type: 包括 String 、 I64 、 Struct 、 Stop 等字段类型。 该字段类型有两个功能:
停止嵌入分析的停止类型
非 Stop 类型用于 Skip(Skip 操作是跳过当前字段,会在「常见问题 - 兼容性」进行讲解)
fied_id:字段序列,在解码时按序列识别字段
len:用于变量类型的字段的长度,例如 String
value:字段值
数据格式
1. 定长数据类型
| 数据类型 | 类型标识(8 位) | 类型大小(单元:字节) |
|---|---|---|
| bool | 2 | 1 |
| byte | 3 | 1 |
| double | 4 | 8 |
| i16 | 6 | 2 |
| i32 | 8 | 4 |
| i64 | 10 | 8 |
2. 变长数据类型
| 数据类型 | 类型标识(8 位) | 类型大小(长度+值) |
|---|---|---|
| string | 11 | 4 + N |
| struct | 12 | 嵌入式数据+一个字符停止(0) |
| map | 13 | 1 + 1 + 4 + N*(X+Y) 【key 类型 + val 类型 + 长度 + 值】 |
| set | 14 | 1 + 4 + N [阀型 + 长度 + 值] |
| list | 15 | 1 + 4 + N [阀型 + 长度 + 值] |
紧凑协议是二进制压缩协议,在大部分字段的编码方式上与 Binary 协议保持一致。区别在于整数类型(包括变量类型的长度)首先采用zigzag编码。实现变量压缩编码,最大化空间节约。
那么问题是,变形和zigzag是什么?
varint 编码
问题解决:固定长度整数类型的绝对值比空间的小时更浪费
根据统计数据,在RPC通信中传输的整数值大多是小,使用固定长度存储是浪费的。
例如,如果你编码了i32类型的7,你可以说前面的3个字符被浪费了:
00000000 00000000 00000000 00000111
解决办法是将整数类型从固定存储器转换为变量存储器(使用单个存储器,你绝对不需要两个)
原理并不复杂,就是将整数按 7bit 分段,每个字节的最高位作为标识位,标识后一个字节是否属于该数据。1 代表后面的字节还是属于当前数据,0 代表这是当前数据的最后一个字节。
以 i32 类型,数值 955 为例,可以看出,由原来的 4 字节压缩到了 2 字节:
当然,varint 编码同样存在缺陷,那就是存储大数的时候,反而会比 binary 的空间开销更大:本来 4 个字节存下的数可能需要 5 个字节,8 个字节存下的数可能需要 10 个字节。
zigzag 编码
解决的问题:绝对值较小的负数经过 varint 编码后空间开销较大 举个
本文由 在线网速测试 整理编辑,转载请注明出处。