How to delay a JMS message in queue before a listener receives it using camel?

北城余情 提交于 2019-12-23 05:29:31

问题


I am trying to delay a message to be in queue for few seconds. But when I use camel delay option, it is not delaying in queue, instead it is immediately consumed, and delaying in the route path. How can we delay messages so that they will be there in queue for few seconds?

My spring with camel configuration looks like below.

<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>

<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">  

    <route id="routeOne" delayer="10000">               
        <from uri="jms://queueone?concurrentConsumers=1"/>          
        <log message="routeOne incoming message ${body}"/>              
        <delay><constant>30000</constant></delay>                       
        <process ref="loggerProcessor"/>                        
    </route>

</camelContext> 

<bean id="loggerProcessor" name="loggerProcessor" class="emh.LoggerProcessor"/>

回答1:


Camel has built in support for the Throttler patter, there's a throttler component. Refer: http://camel.apache.org/throttler.html

Simply add the following to the route and that should delay the message.

<throttle timePeriodMillis="30000">



回答2:


Delay via Camel

Camel delay and throttle will remove (consume) the message from ActiveMQ queue and keep it (in-memory) in the route until processed. Transacted JMS might alleviate issues concerning losing the message, haven't tried that yet. Food for thought.


Delay via ActiveMQ

I got it to work in Spring Boot 2 with Camel and ActiveMQ using the AMQ_SCHEDULED_DELAY header combined with enabling schedulerSupport [1, 2, 3, 4, 5, 6]. This is per JMS 2.0 Delivery Delay.

Note that a message will only appear in the ActiveMQ queue (pending) when there are no active consumers - i.e. application down or Camel route disabled. Configuration below is for using an existing ActiveMQ broker.

application.properties (source)

spring.activemq.broker-url=tcp://localhost:61616

RouteBuilder

from("jms://incomingQueue").setHeader("AMQ_SCHEDULED_DELAY", constant("1000")).inOnly("jms://delayedQueue");  

from("jms://delayedQueue").process(...);

activemq.xml (existing broker installation)

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

For OSX Homebrew found under /usr/local/Cellar/activemq/<version>/libexec/conf.


If you want to use a broker embedded in your application you can use the BrokerService.

By default data is persisted in activemq-data and requires the activemq-kahadb-store dependency - also if you chose JDBC (source). Using brokerService.setPersistent( false ) the store dependency is no longer required, but then the JMS message is stored in-memory again.

@Bean
public BrokerService brokerService()
{
    BrokerService brokerService = new BrokerService();
    brokerService.setSchedulerSupport( true );
    return brokerService;
}

Further examples can be found here and here.



来源:https://stackoverflow.com/questions/33544430/how-to-delay-a-jms-message-in-queue-before-a-listener-receives-it-using-camel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!