通过网络使用 YAML

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

概述

有许多流行的基于文本的协议用于通过网络交换数据。其中包括 XML、FIX 和 JSON。 Chronicle Engine 使用 YAML ,它有一些优点和缺点。

文本不是比二进制慢吗?

文本协议比二进制协议慢。编码数字甚至 unicode 字符串的成本增加了 CPU 的开销。

虽然文本速度较慢,但​​它与二进制文件相比有一个主要优势,即人类可读性。这使得在不使用框架的情况下描述协议和实现接口解决方案变得更加容易。

虽然二进制比文本快,但您可能会发现文本已经足够快,在这种情况下,您需要一种尽可能易于使用的格式。

下面列出了序列化和反序列化具有 6 个不同类型字段的对象的延迟。 TextWire 是 YAML 格式,BinaryWire 是二进制形式,RawWire 和 SBE 是其他二进制格式。

有关详细信息,请参阅 Chronicle-Wire/microbenchmarks

所有时间都以微秒为单位


有线格式
字节 99.9 %平铺 99.99 %平铺 99.999 %平铺
YAML(文本线)
91 2.81 4.94 8.62
YAML(文本线)
91 2.59 4.70 8.58
JSONWire
100 3.11 5.56 10.62
BinaryWire 文本字段
70 1.57 3.42 7.14
BinaryWire 编号字段
44 0.67 2.44 5.93
BinaryWire 字段较少
32 0.65 2.42 5.53
RawWire UTF-8
43 0.49 2.07 4.87
RawWire 8 位
43 0.40 0.57 2.90
字节可编组
39 0.17 0.21 2.13
BytesMarshallable + 停止位编码
28 0.21 0.25 2.40

通常在这些高百分位数中,常见的 Java 库显示出更高的结果,通常是由于 GC 暂停。即使在适度的吞吐量下,这种延迟抖动也开始变得重要,例如,如果您每秒处理 10,000 条消息,则随后的抖动会延迟 14-15 条消息,而不仅仅是一条消息。

格式 字节大小 99.99% 的平铺延迟
杰克逊 100 8.3微秒
BSON + C 字节 96 15.1 微秒
蛇 YAML 88 4,067 微秒
恩赐 JSON 99 32.5 微秒
可外化 197 29.3 微秒

“+ C-Bytes”表示与 Chronicle Bytes 一起使用以回收缓冲区。

虽然 Jackson 取得了 99.99% 的良好结果,但 99.999% 是 1,405 μS。

这些格式是什么样的?

文本线

这种格式有一个 4 字节大小的前缀,它在第一行被解码


 --- !!data
price: 1234
flag: true
text: Hello World!
side: Sell
smallInt: 123
longInt: 1234567890

带有文本字段的 BinaryWire

这是数据自动翻译成文本后的样子。


 --- !!data
price: 1234
flag: true
text: Hello World!
side: Sell
smallInt: 123
longInt: 1234567890

带数字字段的 BinaryWire

这是数据自动翻译成文本后的样子。

没有元数据的 RawWire



 --- !!data
price: 1234
flag: true
text: Hello World!
side: Sell
smallInt: 123
longInt: 1234567890

BytesMarshallable 与停止位编码


 --- !!data
price: 1234
flag: true
text: Hello World!
side: Sell
smallInt: 123
longInt: 1234567890

简单的二进制编码


 --- !!data
price: 1234
flag: true
text: Hello World!
side: Sell
smallInt: 123
longInt: 1234567890

对于全套结果和不同的电线格式

人类可读

XML 和 JSON 是派生的文本格式。它们是 SGML 和 Javascript 的简化形式。这意味着它可以被人类阅读,但不是为此目的而设计的。正如我们将看到的,不是专门为人类可读性而设计的有一些优势。

YAML:一种为人类可读性而设计的格式。

正如我们所见,YAML 的优势在于它专为人类可读性而设计。这意味着它不那么冗长,并且具有更丰富的构造集。

主要缺点是它是为人类可读性(而不是机器可读性)而设计的。它更丰富的结构意味着您可以根据品味安排数据,尽管编写程序以有品味的方式安排数据要困难得多。

一个相关的缺点是不同的实现可能相互不兼容,因为有更多的选项需要支持,其中一些有待解释。例如, 如果需要 ,符号应该放在引号中,不同的库对是否需要引用这样的符号有不同的想法。在规范中,有一些例子,其中带引号的字符串没有被引用。还有两个引号,单引号和双引号。

那么为什么要使用 YAML?

YAML 的优势在于它至少是为人类阅读而设计的。它不是最快的格式,尽管它可以足够快,并且是一种非常可读的格式。如果将其与 XML、JSON 或 FIX 进行比较,它们并不是为速度而设计的,也不是特别可读的。

协议文档

使用 YAML 可以轻松记录需要通过网络发送的内容。我们对不同的功能进行了单元测试,我们记录了文本中发送和接收的内容。我们在这些消息周围添加了一些元数据,并有一个可以直接包含在 我们的文档 中的输出。这意味着我们有信心它是正确的。

作为文本,我们可以包含消息的预期外观,并检测何时即使是微小的更改也很容易改变消息内容。这就像检查字符串匹配一样简单。然后 IDE 可以向您显示多行比较,以便您可以看到已更改的确切字段。

对于 YAML 变慢我们能做些什么?

我们使用高级 API Chronicle Wire ,您可以在其中选择独立关注的确切电汇格式。这意味着一旦我们检查了文本协议是否有效,我们就可以切换到使用二进制协议。我们使用 YAML 的二进制翻译,但我们也可以使用 RAW 数据格式,该格式去除所有元数据以获得最大速度。

我们还有工具可以将“二进制 YAML”自动转换为 YAML,以用于日志记录和调试目的。

结论

通过能够使用 YAML 进行测试和开发,这是开发新解决方案的一种高效方式,可以选择切换到二进制形式以提高速度,这是获得可读性和速度组合的好方法。