节俭是Facebook的高性能开源。轻巧的RPC服务框架是RPC解决方案的完整堆栈,包括序列化和服务通信功能,并支持Cross -Platform/Cross -language。
节俭软件堆栈已明确定义。每一层的组件都松动并插入每一层。如图所示,它可以根据业务领域灵活地组合。直接本身是一个相对较大的主题。本文不涉及所有内容,仅涉及序列化协议。
这是二进制消息格式的示例。IDL定义如下:
代码
代码特定内容
编码含义新闻头1)定义类型 - > t -v模式,即:字段类型 +序列号 +字段值
2)更改长度类型 - > t-l-V模式,即:字段类型 +序列号 +字段长度 +字段值
1.修复长数据类型BOOL21BYTE31DOUBL48I1662I3284I641082。更改长数据类型String114+ NStruct12嵌套数据+ a字节停止符号(0)map131+ 1+ 4+ n*(x+ y)[键类型+ val type+ val type+ lentha4 + N [Val类型 +长度 +值]紧凑协议是二进制压缩协议,与大多数字段中的二进制协议一致。区别在于整数类型(包括变量类型的长度)使用[Zigzag编码首先,然后进行varint压缩编码],以最大程度地提高空间开销。
因此,问题是,什么是Varint和Zigzag?
通过VARINT编码解决的问题:整数类型的生长存储存储的绝对值很小,空间很浪费
根据统计,在传达RPC时,整数值大部分时间都通过,如果浪费了使用固定长度存储,这是浪费的。
例如,可以说编码i32类型7在前3个字节中浪费了:
00000000000000000000000000111
解决方案:将整数类型从固定长度存储转换为长存储(可以用1个字节存储以坚持使用2个字节)
该原理不是复杂的,即整数段通过7位分割,每个字节的最高位用作标识符,而后识别为数据。1代表后来属于当前数据的字节,0意味着这是当前数据的最后一个字节。
以i32类型为例,值为955,可以看出,从原始4字节到2个字节:
当然,Varint编码中也存在缺陷,也就是说,当大量存储数量大时,它将大于二进制空间的空间:4个字节的数量可能需要5个字节,并且存储在中的8个字节的数量可以存储8个字节。可能需要10个字节。
锯齿形编码解决方案问题:varint编码后,具有较小绝对值的负数很大
显然,对于具有较小绝对值的负数,使用Varint后,压缩太多了,很难压缩。头顶上的空间大于二进制编码。
解决方案:负数变为正,因此前指南1转换为前导向0,这很方便varint压缩
算法公式和步骤和演示:
[奇怪的知识]为什么它命名为Zigzag?
因为该算法被负面编码为正义数,所以正数编码为偶数数字。最终效果是正向和负数,就像这样:
节俭不仅支持二进制序列化协议,还支持JSON文本协议
数据格式1.基本类型
2.结构类型
3.地图类型
4.列表类型
现象:服务访问B服务,业务逻辑在短时间内处理,但整个请求15S超时必须是现金。
直接原因:IDL类型已修改;而且只有升级服务器(B服务),没有客户端(服务)没有升级
本质上:字符串是长期的编码,i64是固定的长度代码。由于客户端没有升级,当深层化时,标志时间将用作字符串类型。长期编码是T-L-V模式,是T-L-V模式,因此,较低的4字节4字节的标志时间将在解析过程中翻译成一定长度的标志时间。
Signtime是一个时间戳,大整数,例如:1624206147902,转换为二进制:
00000000 000000000001 0111010101010101010101111111111101 00000001 00111110
低4字节到小数:378
那就是将378字节读取为标志时间的值,该值超过了整个有效负载的大小,最终导致了插座的超时。
[注意]修改类型不一定会导致超时。如果该值的值相对较小,则对较小的分析也相对较小,并且可以保证完成阅读。但是,错误分析可能会导致各种期望,包括:
通过跳过以确保兼容性的额外字段
编译的解析代码基于field_id的开关结构,语法结构直接兼容。
不要破坏兼容性,因为二进制协议不会编码名称
节俭有两个例外,一个是框架中的异常构建,另一个是IDL的异常定义。
框架中的内置异常包括:“方法名称错误”,“消息序列号错误”和“协议错误”。这些异常被捕获并封装在框架中的异常消息中。
用户在IDL中自定义了另一个例外。关键字是异常,与结构没有太大不同。
可选指示该字段可以填充,请求表明必须填充该字段
原始:https://juejin.cn/post/7110108666300203039