我正在尝试使用Apache骆驼从activemq队列“ AMQ:ORIGIN”读取消息。阅读消息后,需要将其传递给两个不同的“ AMQ队列”。但是条件在后面。
要实现上述目标,我创建了两条路线。在第一个路由中,我正在从AMQ队列中读取数据,并向“ AMQ:A”和“ seda:delay”队列进行多播。在第二条路线中,我正在从“ seda:delay”队列中读取,延迟一分钟,然后传递至“ AMQ:B”队列。
如果向“ AMQ:ORIGIN”传递1或10条消息,则可以正常工作
如果我同时向“ AMQ:ORIGIN”队列发送100条消息,则
以下是我的路线。
<route id="read-origin">
<from uri="activemq:ORIGIN"/>
<multicast stopOnException="true">
<to uri="activemq:A"/>
<to uri="seda:delay-route"/>
</multicast>
</route>
<route id="delay-route">
<from uri="seda:delay-route"/>
<delay asyncDelayed="true">
<constant>60000</constant>
</delay>
<to uri="activemq:B"/>
</route>
请提出要实现的更改。
谢谢
答案 0 :(得分:0)
这似乎很明显,因为您将每条消息延迟了1分钟。
如果您向ORIGIN
队列发送100条消息,则所有这些消息到达队列B
的时间为 100分钟。
立即消耗第一条消息,并延迟1分钟。第二个是在第一个交付时(假设有1位消费者在seda队列中)交付并且还延迟了一分钟,依此类推...
我假设您希望已在队列中等待1分钟的邮件在消耗时立即发送。
您可以轻松达到此目的,从而使延迟动态化。
实现一个可计算消息的JMSTimestamp
头(入队时间)与当前时间之间的差的bean。
currentTime - JMSTimestamp
=已经等待
Your minimal delay - alreadyWaited
=传递之前等待的时间(对于排队时间超过延迟的负值邮件,取0)
将此差异用作延迟的值(我使用Java DSL是因为我更了解它)。
from("seda:delay-route").routeId("delay-route")
.delay().expression(method(YourDelayCalculationBean.class))
.to("activemq:B");
像这样,如果您的消息堆积在队列中,则它们可能已经全部消耗掉了,因为它们已经在队列中等待了1分钟以上。
由于评论而添加
好的,抱歉,我没有发现asyncDelayed
。
文档对asyncDelayed
的评价听起来像您期望的那样。但是根据您的评论,听起来Delay EIP不再阻止消费者,而是阻止了自己。
因此seda使用者接收一条消息,将其交给“延迟”,然后继续下一条消息。在发出10条消息(10个线程是Camel的默认线程池大小)后,“延迟”为“满”(所有线程均以固定的1分钟延迟被阻塞)。
因此,由于“延迟”不能再接收任何消息,因此使用者被阻塞。一分钟后,“延迟”可以传递第一条消息,然后继续。
根据您写的路线表现,这只是一个疯狂的猜测。