我正在编写一个死信队列来处理路由中发生的异常。在死信队列中,我计划将每条消息延迟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正在等待延迟。
答案 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值,它似乎不会对请求进行排队,从而阻止调用者。