本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
方法论
ruststream-rumqttc 如何测量自己:三个循环、在真实 MQTT 服务器上的运行、受 Broker 限制的判定计算,以及代码计数。流程就是框架自己的流程(RustStream 方法论),本页说明它在 MQTT 上是什么样子。
三个循环
一个进程把每个场景跑三遍,作为三个循环,它们只有一处不同:承载消息的是什么。
- 裸客户端。 直接驱动
rumqttc:在一个自己的任务上轮询它的事件循环,再通过通道把每个投递交给消费者,与本 crate 的做法相同。消费者解码投递,在 QoS 1 下还要确认它。 - Broker crate。 本 crate,上面什么也没有:Broker 建立连接,描述符打开一个订阅,一个循环从它的流中取出投递、解码并 ack。
- RustStream。 用户写的服务:一个
#[subscriber]处理器及其外围的应用。
其余一切在三个循环中都相同:连接选项(手动确认、Receive Maximum 为 1000、报文上限 1 MiB)、订阅和发布的服务质量、ack 的位置、解码成同一个结构体、载荷字节、带四个工作线程的 tokio 运行时,以及二进制程序。
消息体是 512 字节的 JSON。它解码成一个包含两个整数字段的结构体,因此解码不做内存分配,数字反映的是本 crate,而不是 JSON 解析器。
运行
- 每次运行使用新的主题和新的客户端 ID。 一次运行永远看不到之前的运行留下的东西。
- 消费者先订阅。 随后,一个使用第二个连接的发布者向它发送消息,并且最多领先 768 条。在 QoS 1 下,这让每个投递都留在 1000 的 Receive Maximum 窗口之内;在 QoS 0 下,这让发布者不会跑得太远。
- 在三个循环中,计时窗口都从第一次投递开始,到最后一次投递解码完成时结束,此时它的确认尚未发出。连接和订阅都在窗口之外。
- 消息条数来自一次探测,它在 50000 条消息上测量裸循环的速率,因此在任何机器上,测量的运行都至少持续五秒。
- 各循环交替进行:裸、crate、RustStream,共三轮。每个循环报告它最佳、中位和最差的一轮。
- QoS 2 不在测量之列。 它的四报文握手会让服务器的记账成为测量的对象。
当消费者在运行的大部分时间里都在等待服务器时,该行标为 受 Broker 限制。这是算出来的:一次探测在一个独立的连接上为 20000 个 QoS 1 发布计时,每个发布都等待其 PUBACK,然后取平均值。传输说明一次投递需要多少次往返,二者之积达到每条消息测得时间的一半时,该行就被标记。QoS 0 投递不需要往返,因为没有任何东西返回。QoS 1 投递需要一次,即 PUBACK。往返时间与机器信息一起公布,因此这个计算可以核对。
代码计数
开销图的每个场景都是用户写的服务,基于 MqttBroker,连接同一台服务器,构建时不带 testing 特性,运行在单线程运行时上。另一个线程上的填充程序在测量区间打开之前,以 QoS 1 发布本次运行的全部消息。服务器在会话中保存这些消息,测量区间把它们全部取完。
指令数来自 callgrind,内存分配来自 DHAT。一个场景依次在一次投递、500 次、1000 次上运行。后两次之差是一条消息的稳态开销,单次投递就是冷启动。500 是一次运行取用的最大值:两倍于此就会填满 1000 的 Receive Maximum。
服务器是真实的,所以计数在各次运行之间会有少许变动:套接字怎样把字节交给客户端,取决于时序。某个场景的内存分配超过它声明的下限时,运行失败;这个下限是它的冷启动加上每次投递的稳态开销。与保存的基线对照时,某个场景的指令数多出百分之二,运行也会失败。
自己运行
just bench
这条命令按 docker-compose.test.yml 启动测试环境,运行两个对照场景,停止测试环境,并重写 docs/benchmarks/results.json。它需要几分钟,并且需要独占机器。它会清空 RUSTFLAGS,因此二进制程序不会绑定到构建它的 CPU 上。两条命令都按发布版本的方式构建基准测试,跨 crate 启用完整的链接时优化(fat LTO),因此这些数字描述的正是服务实际使用的代码。
just bench-code
代码计数大约需要一分钟,并且需要 valgrind。它按发布版本的 Cargo.lock 所固定的版本安装基准测试运行器。在 main 上运行 just bench-code --save-baseline=main 记录基线,在分支上运行 just bench-code --baseline=main 与它对照。开头的数字让计数在更少的投递上进行(just bench-code 250);公布的图按 500 次计数。