我们有一个拆分程序将消息推送到不同的队列。还有另一个过程收集和汇总这些消息以供进一步处理。
我们希望在拆分和聚合之间有一个超时。 IIUC聚合超时从第一条消息开始,并且在每条聚合消息之后被重置(它是基于时间间隔的,而不是完整消息)。
解决此问题的最佳解决方案是什么?
答案 0 :(得分:0)
修改强>
这是我能想到的最好的,虽然它有点像黑客。首先,将时间戳保存为消息头,然后将其发布到具有正文的队列:
from("somewhere")
.split(body())
.process(e -> e.getIn().setHeader("aggregation_timeout",
ZonedDateTime.now().plusSeconds(COMPLETION_TIMEOUT)))
.to("aggregation-route-uri");
然后,在使用和聚合时,您使用自定义聚合策略将保存当前组中第一条消息的aggregation_timeout
,然后使用读取该值的completionPredicate
来检查是否超时已过期(或者,如果您以保持消息排序完整的方式进行聚合,则可以从第一条消息中读取标头)。当两条消息之间的间隔很长时,请使用短completionTimeout
作为安全措施:
from("aggregation-route-uri")
.aggregate(bySomething())
.aggregationStrategy((oldExchange, newExchange) -> {
// read aggregation_timeout header from first message
// and set it as property in grouped exchange
// perform aggregation
})
.completionTimeout(1000) // intentionally low value, here as a safeguard
.completionPredicate(e -> {
// complete once the timeout has been reached
return e.getProperty("aggregation_timeout", ZonedDateTime.class)
.isAfter(ZonedDateTime.now());
})
.process(e -> // do something with aggregates);