【问题标题】:Sending large number of messages using spring jmsTemplate使用spring jmsTemplate发送大量消息
【发布时间】:2015-12-08 07:04:59
【问题描述】:

asyncSend 设置为 true 的情况下发送持久消息是否有最佳实践或指导。

我们没有配置事务管理器

我们有大约 40k-50k 的消息是使用配置了

的 jmsTemplate 发送的
org.apache.activemq.pool.PooledConnectionFactory

我们有一个 for 循环,它遍历消息列表并使用它们发送它们

jmsTemplate.convertAndSend(destination, msg)

我们经常看到很多消息丢失,当我们关闭 asyncSend 时,我们获得了可靠性,但生产者的性能下降了 95%

【问题讨论】:

  • 在localhost上使用是不是也一样?我会尝试使用其他 JMS 提供商对其进行测试,以缩小通信的哪一侧出现问题(如果不是一些较低级别的问题:例如传输层)。
  • @Ikrnac 没有生产者 java 客户端,activemq 代理位于不同的物理盒子上。我同意这可能是一个传输层问题,我正在研究的是有没有最好的方法来获得良好的可靠性和良好的性能
  • 我在建议一些调查方法。为了证明它不是传输层,请将它们放在同一台机器上。如果不是传输层,更换 JMS 提供者(例如 HornetQ 好用),看看是 Spring 还是 ActiveMQ 有问题。
  • 顺便说一句,我敢打赌这是 Stack Overflow 帮不了你的事情
  • 你能提供代码吗?你在使用持久化吗?

标签: java spring jms activemq spring-jms


【解决方案1】:

有点猜测,因为问题不是很详细,但无论如何。

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

没有灵丹妙药可以实现最高性能和最高可靠性。很遗憾。

但是,我会尝试在连接工厂上设置producerWindowSize,以在收到代理确认之前允许某些指定数量的数据。确切的值是您需要尝试的,取决于场景以及代理配置/资源。

【讨论】:

  • 一旦我设置了“producerWindowSize”,生产者会等待接收所有之前发送的消息的确认吗?
  • ProducerWindowSize 帮助了我们,峰值负载下几乎没有消息丢失。谢谢
【解决方案2】:

我使用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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2013-02-27
    • 2011-08-23
    • 2018-03-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多