activemq-artemis - ActiveMQ Artemis 生产/消费延迟问题
问题描述
我一直在监控我的微服务应用程序的端到端延迟。每个服务通过 ActiveMQ Artemis 队列松散耦合。
------------- ------------- -------------
| Service 1 | --> | Service 2 | --> | Service 3 |
------------- ------------- -------------
服务 1 作为 HTTP 端点进行侦听并生成到队列 1。服务 2 从队列 1 消费,修改消息并生成到队列 2。服务 3 从队列 2 消费。每个服务在单独的表中向 db 插入一行。从那里我还可以监控延迟。因此,“端到端”进入“服务 1”并退出“服务 3”。
每个服务处理时间保持稳定,并且大多数消息具有几毫秒的合理 e2e 延迟。我使用 400 req/sec 的 JMeter 以恒定速率生产,我可以通过 Grafana 监控它。
我偶尔会注意到这个恒定速率的下降,这可以在整个链条中看到。起初我认为它可能是生产者端(服务 1),因为速率突然下降到 370 req/sec,可能归因于 GC 或可能是 JMeter HTTP 模拟器故障,但这并不能解释为什么某些消息 e2e 延迟会跳转到~2-3 秒。
由于很难重现我的场景,我检查了ActiveMQ Artemis 的负载生成器,并将版本提升到 2.17.0、5.16.2 和 0.58.0。为了匹配我的经纪人 2.17.0。这是一个使用 nfsv4 共享存储的 2 个主/从集群。
下面的命令向单个队列q6生成了 5,000,000 条消息,其中有 4 个生产者/消费者,最大总生产率为400。消息是持久的。中唯一的代码更改artemis-load-generator
是在ConsumerLatencyRecorderTask
我elapsedTime > 1sec
打印出消息 ID 和延迟时。
java -jar destination-bench.jar --persistent --bytes 1000 --protocol artemis --url tcp://localhost:61616?producerMaxRate=100 --out /tmp/test1.txt --name q6 --iterations 5000000 --runs 1 --warmup 20000 --forks 4 --destinations 1
由此我注意到有一些异常消息,其生产/消费延迟接近 2 秒。大多数 (90.00%) 低于 3358.72 微秒。我不确定为什么以及如何发生这种情况?这合理吗?
编辑/更新 我已经运行了几次测试,这是一个较短运行的输出。
java -jar destination-bench.jar --persistent --bytes 1000 --protocol artemis --url tcp://localhost:61616?producerMaxRate=100 --out ~/test-perf1.txt --name q6 --iterations 400000 --runs 1 --warmup 20000 --forks 4 --destinations 1
结果如下
RUN 1 EndToEnd Throughput: 398 ops/sec
**************
EndToEnd SERVICE-TIME Latencies distribution in MICROSECONDS
mean 10117.30
min 954.37
50.00% 1695.74
90.00% 2637.82
99.00% 177209.34
99.90% 847249.41
99.99% 859832.32
max 5939134.46
count 1600000
JVM 线程状态是我在代理上的实际系统中注意到的大量 time_waiting 线程,并且是否存在峰值推送到队列延迟似乎增加了。
目前我的数据正如我所说的那样托管在 ntfs v4 上,如图所示。我读了Artemis 持久性部分
如果日志位于与可能正在写入其他文件的其他进程(例如绑定日志、数据库或事务协调器)共享的卷上,那么磁盘磁头很可能在写入这些文件时在这些文件之间快速移动,从而大大减少表现。
我应该将绑定文件夹移到 vms 磁盘上的 ntfs 之外吗?这会提高性能吗?我不清楚。
这对Shared Store HA有何影响?
解决方案
我启动了一个新的 ActiveMQ Artemis 2.17.0 的默认实例,克隆并构建了artemis-load-generator(进行了修改以立即对处理时间超过 1 秒的消息发出警报),然后运行您运行的相同命令。我让测试在我的本地机器上运行了大约一个小时,但我没有让它完成,因为它需要 3 个多小时(500 万条消息,每秒 400 条消息)。在大约 100 万条消息中,我只看到了 1 条“异常值”——当然与您所看到的 10% 相差无几。值得注意的是,这段时间我仍在使用我的电脑进行正常的开发工作。
在这一点上,我不得不将此归因于某种环境问题,例如:
- 垃圾收集
- 低性能磁盘
- 网络延迟
- CPU,RAM等不足。
推荐阅读
- java - 无法模拟 Spring WebClient 调用
- huawei-mobile-services - 组件A的样式不能在文本组件中动态修改。我怎么解决这个问题?
- .net - IIS 中的 .Net Web API 托管(API 使用 Bearer Token 进行身份验证)
- javascript - javascript计算数字函数中的位数问题
- reactjs - 在 params 中传递函数时,在导航状态中发现了不可序列化的值
- nlp - 每年的预训练词嵌入
- flutter - 我在尝试运行 Flutter 应用程序时收到此错误:找不到名为“devtools-server-address”的选项
- java - 解析到 POJO 时如何在 JSON 对象中排除 Null 列表
- node.js - Axios - 错误:请求失败,状态码为 503
- c++ - 围绕 new/delete 编写内存分析包装器的合适方法是什么?