使用Spring的jmsTemplate发送大量消息

3

是否有关于将asyncSend设置为true发送持久消息的最佳实践或指导?

我们没有配置事务管理器

我们有大约40k-50k条消息使用配置了jmsTemplate发送

org.apache.activemq.pool.PooledConnectionFactory

我们有一个for循环,它遍历消息列表并使用特定的方法发送它们。
jmsTemplate.convertAndSend(destination, msg)

我们经常会遇到许多信息丢失的情况,当我们关闭asyncSend时,虽然可以获得可靠性,但生产者的性能将下降95%。

当您在本地主机上使用它时是否相同?我会尝试使用其他JMS提供程序进行测试,以缩小通信问题的范围(如果不是一些低级问题:例如传输层)。 - luboskrnac
@Ikrnac 没有生产者 Java 客户端,ActiveMQ 经纪人位于不同的物理盒子上。我同意这可能是一个传输层问题,我正在寻找的是有没有最好的方法来实现良好的可靠性和良好的性能。 - Dhananjay
我建议采用一些调查方法。为了证明它不是传输层的问题,请在同一台机器上进行定位。如果这不是传输层的问题,更换JMS提供商(例如,HornetQ易于使用),以找出是Spring还是ActiveMQ引起了问题。 - luboskrnac
顺便说一句,我敢打赌这是 Stack Overflow 无法帮助你的事情。 - luboskrnac
你能提供代码吗?你正在使用持久化吗? - developer
2个回答

1

鉴于问题描述不够详细,以下是一些猜测。

根据配置,ActiveMQ 可能对队列设置内存限制(持久和非持久消息可能有所不同)。因此,当内存用完时,您的 asyncSend 调用将忽略警告并继续向“黑洞”传递消息,直到消费者释放内存。

没有银弹可以同时实现最大性能和最大可靠性。不幸的是。

然而,我建议在连接工厂上设置 producerWindowSize,以允许在经纪人确认之前接收一定量的数据。确切的值需要根据场景以及经纪人配置/资源进行尝试。


一旦我设置了“producerWindowSize”,生产者会等待接收所有先前发送的消息的确认吗? - Dhananjay
1
ProducerWindowSize对我们很有帮助,在高峰期负载下几乎没有消息丢失。谢谢。 - Dhananjay

1
我使用 ProducerCallback 解决了这个问题。
List<String> messageTexts = prepareListOfMessaeTexts();
ProducerCallback producerCallback = (session, producer) -> {
    Topic destination = session.createTopic(myTopicName);
    for (String messageText : myMessagmessageTextseBodies) {
        producer.send(destination, session.createTextMessage(messageText));
    }
    return null;
};
jmsTemplate.execute(producerCallback);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接