【发布时间】:2021-09-11 11:20:49
【问题描述】:
我有一个在 Docker 容器中运行的 Artemis 代理 (2.10.1),它有一个地址,但有许多 (500+) 个队列。每个队列都有一个过滤属性,它们不重叠,路由类型为多播。
broker
- address: example
- multicast
- queue: dummy1 (filter: dummy=1)
- queue: dummy2 (filter: dummy=2)
- queue: dummy3 (filter: dummy=3)
- ...
当客户端连接时,客户端和代理的 cpu 使用率从 ~5% 上升到 ~40%,根据 htop(~20% 正常 + ~20% 内核)。 JMX 报告约 10% 的 CPU 使用率。将 htop 更改为树视图时,我可以看到 ~10% 线程和许多 0.x% 线程。队列是空的,我既不生产也不消费消息。整个系统(应该)处于空闲状态。客户端建立一个连接,但每个队列一个会话,导致 500 多个会话。
我的配置有什么问题?我看不出有这样的 CPU 使用率和负载的原因。
更新:
我做了更多测试,结果发现 CPU 使用率/负载只有在涉及 Docker 时才会发生。
- 代理在主机 A 上的 Docker 容器中运行,纯 artemis-core 客户端在主机 B 上运行(无 Docker):
- 代理在主机 A 上的 Docker 容器中运行,纯 artemis-jms 客户端在主机 A 上运行(无 Docker):
- 代理在主机 A 上的 Docker 容器中运行,Spring Boot 客户端在主机 B 上运行 starter-artemis(没有 Docker):5-10% 的 CPU 使用率
- 在主机 A 上的 Docker 容器中运行的代理,在主机 A 上运行的 Docker 容器中带有 starter-artemis(使用 JMS)的 Spring Boot 客户端:CPU 使用率约为 40%
我还在做更多的研究,只是想让你知道现在的状态,不再责怪阿尔忒弥斯展示了不好的数字。
顺便说一句,一个有趣的附加信息:在空闲期间,两个应用程序仅使用 artemis 依赖项(核心和 jms),每 30 秒只交换一个 ping 消息。使用 starter-artemis 嵌入到 Spring Boot 中的应用程序非常健谈。还不能告诉你这是关于什么的,除了我看到了一些关于 hornetq 强制交付序列 的内容。我假设由于消息的数量,CPU 使用率从
更新 2:
带有 starter-artemis 的 Spring Boot 是健谈的,因为默认情况下它使用 DefaultContainerFactory,它会轮询。如果在给定的超时时间内没有任何消息,它会发出 force pull 命令,这就是那些 hornetq 强制传递 seq 消息的原因。在我的 core/jms 测试中,我使用了异步消息处理程序,如果您切换到 SimpleContainerFactory,它由 Spring Boot starter-artemis 提供。
【问题讨论】:
-
在此期间您是否从代理收集了任何线程转储以查看问题可能是什么?如果是这样,他们表示了什么?如果不是,为什么?另外,我强烈建议您升级到最新版本。
-
是的,我查看了线程转储,但没有看到任何可以解释该行为的内容。只是一些 nio 轮询线程。也许那是因为应用程序本身不是问题。我刚刚用最近的一些发现更新了答案。事实证明,Docker 似乎至少以某种方式参与了 CPU 使用率的增加。
标签: spring-boot docker activemq-artemis