Apache Camel:Delayer的异步延迟无法正常运行

时间:2014-01-29 20:07:27

标签: activemq apache-camel

我正在编写一个死信队列来处理路由中发生的异常。在死信队列中,我计划将每条消息延迟1天(或任何其他长时间)。我写的代码当前正在延迟消息,除非不会异步延迟,并且在等待先前延迟的消息等待延迟期间时消息最终得到备份。

<route>
   <from uri="activemq:queue:foo"/>
   <delay asyncDelayed="true">
       <constant> 60000 </constant>
   </delay>
   <to uri="activemq:aDelayedQueue"/>
</route>

我读到asyncDelayed =“true”应该安排将来要执行的任务来处理路由的后半部分,除非我尝试运行上面的代码时消息最终备份在foo队列中同时滴流在aDelayedQueue中一次1个。

为什么会这样做,是否有可以解决这个问题的东西?

谢谢!

编辑,我找到了一个解决方法,但我很想知道最初出了什么问题。

再次重述问题。这是我的队列管道的样子:

QueueA - &gt; QueueB - &gt; QueueC

QueueB拉取QueueA中的消息。目标是每个消息在被发送到QueueC之前在QueueB中停留X个时间。上面的代码段放在QueueB中。我面临的问题是,如果5个消息同时到达QueueA,QueueB只会将其中一条消息拉入,等待60秒,然后将该消息发送给QueueC。我的预期功能是将所有5条消息放到QueueB上,在这些消息放置到QueueC上之前它们将静置60秒。最初的问题是消息开始堆积在QueueA中,因为QueueB正在等待延迟。

2 个答案:

答案 0 :(得分:0)

JMS客户端路由逐个处理消息而不是并行处理消息。只有当一条消息离开队列时,下一个队列才能进入该路由。因此,如果一条消息被延迟,则不会从JMS队列中读取其他消息。

除了你的解决方法之外,你可以将你的路线并行化:

<route>
    <from uri="activemq:queue:foo"/>
    <to uri="seda:delayer"/>
</route>

<route>
    <from uri="seda:delayer?concurrentConsumers=1000"/>
    <delay asyncDelayed="true">
         <constant> 60000 </constant>
    </delay>
    <to uri="activemq:aDelayedQueue"/>
</route>

但是,即使您的客户端路由关闭,您的解决方法AMQ_SCHEDULED_DELAY也会更加强大,请参阅Persisting failed messages in Camel's SEDA queue

答案 1 :(得分:0)

我有完全相同的问题,除了路由是vm路由而不是activemq。因此,以下路由定义将同步阻止:

from("vm:a").
    throttle(1).asyncDelayed(). 
        to("vm:b");

但是,当我添加maximumRequestsPerPeriod值时,它按预期工作:

from("vm:a").
    throttle(1).asyncDelayed().maximumRequestsPerPeriod(100L).
        to("vm:b");

如果您没有提供maximumRequestsPerPeriod值,它似乎不会对请求进行排队,从而阻止调用者。