Spring JMS(ActiveMQ)延迟了消息的传递

时间:2014-08-04 14:31:00

标签: java spring jms activemq spring-jms

我们正在尝试在某些JMS消息上设置延迟,以便只在x时间之后将消息添加到侦听器接收的队列中。到目前为止,我们尝试了两种不起作用的方法。

1)根据spring文档,我们可以在JMSTemplate上设置传递延迟。这是我们尝试的示例代码:

@Autowired
private JmsTemplate jmsTemplate;

...
long deliveryDelay = ...;
this.jmsTemplate.setDeliveryDelay(deliveryDelay);
this.jmsTemplate.convertAndSend(
                    queue.getName(),
                    event);
...

但是,我们得到以下异常,即使我们的spring jms版本是4.0.5:

java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0

2)我们也尝试设置邮件本身的延迟,但看起来延迟被忽略了,邮件仍然立即传递。

@Component
public class MyMessageConverter implements MessageConverter {

...

@Override
public Message toMessage(Object eventObject, Session session) throws JMSException, MessageConversionException {

...
long deliveryDelay = ...;
objectMessage.setLongProperty(
                  ScheduledMessage.AMQ_SCHEDULED_DELAY,
                  deliveryDelay);
return objectMessage;
}
}

spring xml中的jmsTemplate定义:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="cachingConnectionFactory" />
    <property name="messageConverter" ref="myMessageConverter" />
    <property name="sessionTransacted" value="true" />
</bean>

有没有人对如何实现延迟消息传递的问题/其他想法有任何建议? 谢谢!

8 个答案:

答案 0 :(得分:3)

评论给出了答案。默认情况下,禁用预定的消息支持。您必须在documentation页面上提到的代理XML配置文件中启用它。

启用了调度程序支持的示例Broker标记:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">

答案 1 :(得分:1)

需要做两件事来解决这个问题。

  • 默认情况下,禁用计划的邮件支持。我们必须在代理XML配置文件中启用它。
  

经纪人xmlns =“ http://activemq.apache.org/schema/core”   brokerName =“ localhost” dataDirectory =“ $ {activemq.data}”   schedulerSupport =“ true”>

  • 设置发送消息之前的延迟。

    public void send(Object object){     log.info(“ put <” + object +“>”);     jmsTemplate.convertAndSend(QUEUE_NAME,object,m-> {          m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY,10000);         返回m;     }); }

答案 2 :(得分:0)

同样根据ActiveMQ BrokerService类的方法,您应该将持久性配置为具有使用调度程序功能的能力。

public boolean isSchedulerSupport() {
    return this.schedulerSupport && (isPersistent() || jobSchedulerStore != null);
}

答案 3 :(得分:0)

  jmsTemplate.convertAndSend(destination, message, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws JMSException {
                message.setIntProperty("JMS_OracleDelay", 200);
                return message;
            }
        });

答案 4 :(得分:0)

activemq包中不支持JMS 2.0。尝试使用artemis。尝试从

替换包名称
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
        <version>1.5.6.RELEASE</version> 
    </dependency>

进入

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-artemis</artifactId>
        <version>1.5.6.RELEASE</version> 
    </dependency>

并添加application.properties

    spring.artemis.mode=native
    spring.artemis.host=localhost
    spring.artemis.port=61616
    spring.artemis.user=admin
    spring.artemis.password=admin

关注此article

答案 5 :(得分:0)

文档http://activemq.apache.org/delay-and-schedule-message-delivery.html

示例:在10秒钟内收到消费者的消息

public void send(Object object) {
    log.info("put <" + object + ">");
    jmsTemplate.convertAndSend(QUEUE_NAME, object, m -> {
        m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000);
        return m;
    });
}

答案 6 :(得分:0)

  1. 我在活动的mq配置xml中添加了schedulerSupport=true。请不要忘记在配置更改后重新启动活动的mq服务器。重新启动并登录到activemq管理控制台上的“预定”标签后,您将看到预定的消息详细信息。

  2. jmsTemplate.setDeliveryDelay对我不起作用,因此我添加了以下代码:

    jmsTemplate.convertAndSend(queueName, object, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws JMSException {
                message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, scheduledDelay);
                return message;
            }
        });

请注意:一开始它对我不起作用。但是需要在activeMQ服务器上重新启动以反映config中的更改

答案 7 :(得分:-2)

broker-url: vm://embedded?broker.persistent=true&broker.useShutdownHook=false&broker.schedulerSupport=true