Splitter / Aggregator具有火灾/遗忘和超时

时间:2016-10-05 09:26:30

标签: apache-camel

我们有一个拆分程序将消息推送到不同的队列。还有另一个过程收集和汇总这些消息以供进一步处理。

我们希望在拆分和聚合之间有一个超时。 IIUC聚合超时从第一条消息开始,并且在每条聚合消息之后被重置(它是基于时间间隔的,而不是完整消息)。

解决此问题的最佳解决方案是什么?

1 个答案:

答案 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);