使用 Spring 的 JmsTemplate 向 ActiveMQ Artemis 发送消息非常慢
Sending messages to ActiveMQ Artemis with Spring's JmsTemplate is very slow
我只能发布大约 1600 个小字符串 msgs/sec 到 Apache Artemis。我试过两台机器并获得了相同的性能。我期待更快的东西。这是单线程的预期发送速度吗?我应该用几个线程并行发送吗?
代理和发布应用在同一台主机上。没有听众订阅该主题。我正在使用:
- JMSAPI
- 阿帕奇阿蒂米斯 2.20.0
- Java 18 位 64 位
- 甲骨文Linux8
- Spring 启动 2.6.5
Spring 引导 application.properties
包括:
spring.jms.pub-sub-domain=true
broker.xml
有:
<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);
像这样在 Spring 中设置 JmsTemplate:
@Autowired
JmsTemplate jmsTemplate;
@PostConstruct
void setup() {
JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory();
poolingFactory.setConnectionFactory(new ActiveMQConnectionFactory());
jmsTemplate.setConnectionFactory(poolingFactory);
}
我认为您 运行 和 Spring 的 JmsTemplate
是 long-standing anti-pattern。简而言之,它会在每次发送消息时 创建和关闭 JMS 连接、会话和生产者。它并非设计用于裸露的 javax.jms.ConnectionFactory
实现。它旨在与提供某种池化的实现一起使用。
作为 proof-of-concept 我启动了一个新的 ActiveMQ Artemis 2.20.0 实例并在 broker.xml
中设置了 <persistence-enabled>false</persistence-enabled>
。然后我 运行 这个命令:
$ ./artemis producer --destination topic://foo --threads 50 --message-count 100000
此命令将启动 50 个线程,每个线程将使用核心 JMS 客户端向 JMS 主题 foo
发送 100,000 条消息,总计 5,000,000 条消息。在我的笔记本电脑上,该命令在大约 40.6 秒内完成,平均速率为 122,980.1 msgs/sec,这比您看到的 1,600 快得多。
ActiveMQ Artemis 有一个 non-blocking 架构,旨在最大限度地提高吞吐量,因此 运行 仅几个线程并不是测试性能的好方法。我建议修改您的“测试”以使用具有更多线程的池连接工厂,或者使用代理附带的 command-line 工具。 This pool was forked from the ActiveMQ project and it is battle tested. You could also potentially use Spring's CachingConnectionFactory
一个简单的解决方案。
您可能也对新 performance tools just released with ActiveMQ Artemis 2.21.0 感兴趣。
我只能发布大约 1600 个小字符串 msgs/sec 到 Apache Artemis。我试过两台机器并获得了相同的性能。我期待更快的东西。这是单线程的预期发送速度吗?我应该用几个线程并行发送吗?
代理和发布应用在同一台主机上。没有听众订阅该主题。我正在使用:
- JMSAPI
- 阿帕奇阿蒂米斯 2.20.0
- Java 18 位 64 位
- 甲骨文Linux8
- Spring 启动 2.6.5
Spring 引导 application.properties
包括:
spring.jms.pub-sub-domain=true
broker.xml
有:
<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);
像这样在 Spring 中设置 JmsTemplate:
@Autowired
JmsTemplate jmsTemplate;
@PostConstruct
void setup() {
JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory();
poolingFactory.setConnectionFactory(new ActiveMQConnectionFactory());
jmsTemplate.setConnectionFactory(poolingFactory);
}
我认为您 运行 和 Spring 的 JmsTemplate
是 long-standing anti-pattern。简而言之,它会在每次发送消息时 创建和关闭 JMS 连接、会话和生产者。它并非设计用于裸露的 javax.jms.ConnectionFactory
实现。它旨在与提供某种池化的实现一起使用。
作为 proof-of-concept 我启动了一个新的 ActiveMQ Artemis 2.20.0 实例并在 broker.xml
中设置了 <persistence-enabled>false</persistence-enabled>
。然后我 运行 这个命令:
$ ./artemis producer --destination topic://foo --threads 50 --message-count 100000
此命令将启动 50 个线程,每个线程将使用核心 JMS 客户端向 JMS 主题 foo
发送 100,000 条消息,总计 5,000,000 条消息。在我的笔记本电脑上,该命令在大约 40.6 秒内完成,平均速率为 122,980.1 msgs/sec,这比您看到的 1,600 快得多。
ActiveMQ Artemis 有一个 non-blocking 架构,旨在最大限度地提高吞吐量,因此 运行 仅几个线程并不是测试性能的好方法。我建议修改您的“测试”以使用具有更多线程的池连接工厂,或者使用代理附带的 command-line 工具。 This pool was forked from the ActiveMQ project and it is battle tested. You could also potentially use Spring's CachingConnectionFactory
一个简单的解决方案。
您可能也对新 performance tools just released with ActiveMQ Artemis 2.21.0 感兴趣。