如果使用延迟,Apache骆驼不会将所有消息发送给AMQ

时间:2020-06-02 21:05:03

标签: apache-camel

我正在尝试使用Apache骆驼从activemq队列“ AMQ:ORIGIN”读取消息。阅读消息后,需要将其传递给两个不同的“ AMQ队列”。但是条件在后面。

  1. 消息应立即传递到队列“ AMQ:A”。
  2. 延迟一分钟后,消息应传递到队列“ AMQ:B”。

要实现上述目标,我创建了两条路线。在第一个路由中,我正在从AMQ队列中读取数据,并向“ AMQ:A”和“ seda:delay”队列进行多播。在第二条路线中,我正在从“ seda:delay”队列中读取,延迟一分钟,然后传递至“ AMQ:B”队列。

如果向“ AMQ:ORIGIN”传递1或10条消息,则可以正常工作

如果我同时向“ AMQ:ORIGIN”队列发送100条消息,则

  1. 所有100条消息均传递到“ AMQ:A”队列中
  2. 仅10或12条消息传递到“ AMQ:B”队列。其余仅停留在路线上。

以下是我的路线。

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

请提出要实现的更改。

谢谢

1 个答案:

答案 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分钟延迟被阻塞)。

因此,由于“延迟”不能再接收任何消息,因此使用者被阻塞。一分钟后,“延迟”可以传递第一条消息,然后继续。

根据您写的路线表现,这只是一个疯狂的猜测。