【问题标题】:ActiveMQ delayed delivery of messages in Spring BootSpring Boot 中的 ActiveMQ 延迟消息传递
【发布时间】:2016-11-19 03:16:41
【问题描述】:

我的问题与Spring JMS(ActiveMQ) delayed delivery of messages 非常相似,但与 spring-boot 自动配置器更相关

我正在尝试使用jmsTemplate.setDeliveryDelay 方法,但它会抛出java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0

我试图从 http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html 找到正确的属性,但找不到代理 schedulerSupport 选项。

目前我的application.properties为空,我的JmsListenerContainerFactory定义如下

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

    configurer.configure(factory, connectionFactory);
    return factory;
}

而我的 pom 只包含

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

在 1.4.1.RELEASE 中使用 spring-boot-starter-parent

问题是:是否可以使用 SpringBoot 配置将 schedulerSupport 设置为 true?

如果需要,这里是我的发件人

public void send(String message) {
    System.out.println("Im sending this message " + message);
    jmsTemplate.setDeliveryDelay(5000);
    jmsTemplate.convertAndSend(Beans.QUEUE_NAME, message);
}

和接收者

@JmsListener(destination = Beans.QUEUE_NAME, containerFactory = "myFactory")
public void receiveMessage(String message) {
    System.out.println("Received this message <" + message + ">");
}

提前致谢


更新:我尝试将它放在消息属性中,例如文档 http://activemq.apache.org/delay-and-schedule-message-delivery.html ,但它不起作用

@Bean
public MessageConverter messageConverter() {
    MessageConverter converter = new MessageConverter(){
        @Override
        public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
            if (!(object instanceof MyPojo)) {
                throw new MessageConversionException("not agreed Pojo!");
            }
            MyPojo pojo = (MyPojo) object;

            Message message = session.createTextMessage(pojo.getMessage());
            message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, pojo.getScheduledWait());
            return message;
        }
        @Override
        public Object fromMessage(Message message) throws JMSException, MessageConversionException {
            return message;
        }
    };
    return converter;
}

【问题讨论】:

  • 这个问题你解决了吗?
  • 我在下面回答了我自己的问题(这是第二个问题)。最后我使用了另一个启动器(artemis)。

标签: java spring-boot jms activemq


【解决方案1】:

模板正在尝试调用 JMS 2.0 传递延迟方法,但 ActiveMQ 客户端和代理仅支持 JMS 1.1,因此您将收到此错误。您可以通过使用定义的值here 设置消息中的消息属性,来使用 ActiveMQ 对计划传递的支持。

目前尚不完全清楚如何从 Spring Boot 启用调度程序,但我猜你需要提供自己的 Broker URI 来启用它,例如:

broker:(tcp://localhost:61616)?persistent=true&useJmx=false&schedulerSupport=true

【讨论】:

  • 感谢您的想法。我更新了 MessageConverter 以使用 Activemq 属性,但它仍然没有安排。它立即交付。我用代码更新了问题
  • 确保您已启用调度程序支持代理端
  • 这是问题的一部分:如何在 spring-boot 自动配置中添加调度程序支持
  • 没有线索,但如果您想出应该解决问题的部分,经纪人需要打开它以支持延迟交付。
【解决方案2】:

我不知道是不是作弊,但解决问题的方法是将启动器从 activemq 更改为 artemis (https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-artemis)

显然,默认情况下,spring 将 Artemis 配置为 JMS 2.0 接口。这样你就可以访问 setDeliveryDelay 方法了。

【讨论】: