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