使用Spring的JMSTAME将消息发送到ActiveMQ Artemis非常慢

发布于 2025-01-18 00:59:02 字数 1621 浏览 0 评论 0原文

我只能向Apache Artemis发布大约1600个小字符串MSGS/sec。我已经尝试了两台机器,并获得了相同的性能。我期望的速度更快。那是一个线程的预期发送速度吗?我应该与几个线程并行化发送吗?

经纪人和出版应用程序在同一主机上。没有听众订阅该主题。我正在使用:

  • JMS API
  • APACHE ARTEMIS 2.20.0
  • JAVA 18 64位
  • Oracle Linux 8
  • Spring Boot 2.6.5

Spring Boot application.properties include:

spring.jms.pub-sub-domain=true

broke> broker.xml has:

<persistence-enabled>false</persistence-enabled>

Spring的JMstemplate是这样的设置(这是错误的):

import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.messaginghub.pooled.jms.JmsPoolConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
 ...
JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory();
poolingFactory.setConnectionFactory(new ActiveMQConnectionFactory());
jmsTemplate = new JmsTemplate(poolingFactory);

要发布消息,我只是在循环中调用此消息:

jmsTemplate.convertAndSend(jmsQueue, message);

在弹簧中设置JMstemplate这样的工作:

@Autowired
JmsTemplate jmsTemplate;

@PostConstruct
void setup() {
        JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory();
        poolingFactory.setConnectionFactory(new ActiveMQConnectionFactory());
        jmsTemplate.setConnectionFactory(poolingFactory);
}

I can only publish about 1600 small string msgs/sec to Apache Artemis. I have tried on two machines and gotten same performance. I expected something much faster. Is that expected sending speed for a single thread? Should I parallelize the sending with a few threads?

The broker and the publishing app are on the same host. No listener is subscribed to the topic. I'm using:

  • JMS API
  • Apache Artemis 2.20.0
  • Java 18 64 bit
  • Oracle Linux 8
  • Spring Boot 2.6.5

Spring Boot application.properties includes:

spring.jms.pub-sub-domain=true

broker.xml has:

<persistence-enabled>false</persistence-enabled>

Spring's JmsTemplate is setup like this (THIS WAS WRONG):

import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.messaginghub.pooled.jms.JmsPoolConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
 ...
JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory();
poolingFactory.setConnectionFactory(new ActiveMQConnectionFactory());
jmsTemplate = new JmsTemplate(poolingFactory);

To publish messages I just call this in a loop:

jmsTemplate.convertAndSend(jmsQueue, message);

Setting up the JmsTemplate in Spring like this works:

@Autowired
JmsTemplate jmsTemplate;

@PostConstruct
void setup() {
        JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory();
        poolingFactory.setConnectionFactory(new ActiveMQConnectionFactory());
        jmsTemplate.setConnectionFactory(poolingFactory);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨落星ぅ辰 2025-01-25 00:59:02

我认为您正在使用 Spring 的 JmsTemplate 遇到 长期存在的反模式。简而言之,它每次发送消息时都会创建和关闭 JMS 连接、会话和生产者。它并非设计用于与裸露的 javax.jms.ConnectionFactory 实现一起使用。它旨在与提供某种池化的实现一起使用。

作为概念验证,我启动了 ActiveMQ Artemis 2.20.0 的新实例,并在 broker.xmlfalse 设置代码>.然后我运行以下命令:

$ ./artemis producer --destination topic://foo --threads 50 --message-count 100000

该命令将启动 50 个线程,每个线程将使用核心 JMS 客户端向 JMS 主题 foo 发送 100,000 条消息,总共 5,000,000 条消息。在我的笔记本电脑上,该命令在大约 40.6 秒内完成,平均速率为 122,980.1 条消息/秒,这比您看到的 1,600 条消息要快得多。

ActiveMQ Artemis 具有非阻塞架构,旨在大规模最大化吞吐量,因此仅运行几个线程并不是测试性能的好方法。我建议修改您的“测试”以使用具有更多线程的池连接工厂,或者可能使用代理附带的命令行工具。 此池是从 ActiveMQ 项目中分叉出来的,并且经过了实际测试。您还可以使用 Spring 的 CachingConnectionFactory 一个简单的解决方案。

您可能还对新的性能工具感兴趣刚刚与 ActiveMQ Artemis 2.21.0 一起发布。

I think you're running into a long-standing anti-pattern with Spring's JmsTemplate. In short, it creates and closes a JMS connection, session, and producer every time it sends a messages. It was not designed to be used with a bare javax.jms.ConnectionFactory implementation. It was meant to be used with an implementation that provides some kind of pooling.

As a proof-of-concept I spun up a fresh instance of ActiveMQ Artemis 2.20.0 and set <persistence-enabled>false</persistence-enabled> in broker.xml. Then I ran this command:

$ ./artemis producer --destination topic://foo --threads 50 --message-count 100000

This command will start 50 threads which will each use the core JMS client to send 100,000 messages to the JMS topic foo for a total of 5,000,000 messages. On my laptop that command finished in around 40.6 seconds for an average rate of 122,980.1 msgs/sec which is significantly faster than the 1,600 you're seeing.

ActiveMQ Artemis has a non-blocking architecture designed to maximize throughput at scale so running just a couple of threads isn't a good way to test performance. I recommend revising your "test" to use a pooling connection factory with significantly more threads or perhaps use the command-line tools that ship with the broker. This pool was forked from the ActiveMQ project and it is battle tested. You could also potentially use Spring's CachingConnectionFactory for a simple solution.

You may also be interested in the new performance tools just released with ActiveMQ Artemis 2.21.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文