Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JMS(ActiveMQ) delayed delivery of messages

We're trying to set a delay on some JMS messages, so that a message will only be added to the queue/ received by the listener after x time. So far we've tried 2 approaches that didn't work.

1) According to the spring documentation, we can set the delivery delay on the JMSTemplate. This is the sample code we tried:

@Autowired
private JmsTemplate jmsTemplate;

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

However, we get the following exception, even though our spring jms version is 4.0.5:

java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0

2) We also tried setting the delay on the message itself, but it looks like the delay was ignored, and the message was delivered immediately anyway.

@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;
}
}

The jmsTemplate definition in the spring xml:

<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>

Does anyone has any suggestions on what the problems are / other ideas on how to achieve delayed messaging? Thanks!

like image 759
Ayelet Avatar asked Aug 04 '14 14:08

Ayelet


2 Answers

The comments give the answer. By default scheduled message support is disabled. You must enabled it in the broker XML configuration file as mentioned on the documentation page.

An example Broker tag with scheduler support enabled:

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

You must of course restart the broker in order for configuration changes to take affect. Then when you send a message you need to add the JMS headers that tell the broker what type of delay you want.

message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, scheduledDelay);
like image 142
Tim Bish Avatar answered Sep 21 '22 16:09

Tim Bish


Two things needs to be done to resolve this.

  • By default scheduled message support is disabled. We must enabled it in the broker XML configuration file.

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

  • Set the delay before sending the message.

    public void send(Object object) {
        log.info("put <" + object + ">");
        jmsTemplate.convertAndSend(QUEUE_NAME, object, m -> {
           m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000);
           return m;
        });
    }
    
like image 21
dassum Avatar answered Sep 24 '22 16:09

dassum