我有一个场景,我得到输入消息A.消息A必须分成3种不同类型的消息,并转发到其他路由。消息以准确的顺序到达是很重要的,即。 A-1必须在A-2之前发送,必须在A-3之前发送。
为此,我做了以下(大纲):
from("activemq:queue:somequeue-local")
.multicast().to("direct:a1","direct:a2","direct:a3");
from("direct:a1)
//split incoming message and prepare output document for A-1
.to("activemq:queue:otherqueue")
.from("direct:a2)
//split incoming message and prepare output document for A-2
.to("activemq:queue:otherqueue")
.from("direct:a3)
//split incoming message and prepare output document for A-3
.to("activemq:queue:otherqueue")
在另一个环境中,负责将信息发送到外部系统,我有
.from("activemq:queue:otherqueue?maxMessagesPerTask=1&concurrentConsumers=1&maxConcurrentConsumers=1")
// do different stuff based on which type we are called with then end with
.beanref("somebean","writeToFileAndCallImportbat");
现在,我的问题是,当我到达接收器时,我以随机顺序获取消息。有时A-1,A-3,A-2,有时是右,A-1,A-2,A-3。
我尝试将JMSXGroupID和JMSXGroupSeq添加到邮件中,但没有任何运气。
我也尝试完全跳过MQ部分,并使用direct-vm:来调用共享接收器,但是看起来我一次有三个同时调用接收器,并且仍然是随机执行顺序。
我的印象是多播会按顺序运行,除非另有提示?
这种方法是否存在根本性的错误?
我使用的是Camel版本2.12。
或者,更明白地说:
答案 0 :(得分:0)
如果您使用Splitter pattern,请检查流式传输属性是否设置为false。
如果启用,则Camel将以流式方式拆分,这意味着它将以块的形式拆分输入消息。这减少了内存开销。例如,如果您拆分大消息,建议启用流式传输。如果启用了流式传输,则子消息回复将无序聚合,例如按照它们返回的顺序聚合。如果禁用,Camel将按照拆分的顺序处理子消息回复。
答案 1 :(得分:0)
所以,事实证明,这毕竟不是多播的问题。
相反,在我的每个子路线中,我都这样做了:
.split(..stax(SpecialClass)).streaming()
.beanRef("transformationBean","somefunction")
.aggregate(constant("1"), new MyAggregator())
.completionTimeout(5000)
.completionSize(1000)
.to(writeToFileAndRunBat)
其中,我假设“处理拆分中的所有元素,如果您未在5秒内完成或在1000个元素之后完成,则突破”。
我把它改成了
.split(..stax(SpecialClass), , new MyAggregator()).streaming()
.beanRef("transformationBean","somefunction")
.end()
.to(writeToFileAndRunBat)
想到它,它是完全合理的,因为第一个版本不能真正知道我们何时完成,而最后一个(我假设)只是遍历拆分中的所有元素并为每个元素调用聚合器。
另外,我必须在第一个版本中使用.end()。所以我猜整件事只是随机行动。