我正在使用Spring Integration(版本5.0.0.M2
开发一个应用程序,因为我需要动态流注册功能),并且在某些时候我必须根据它们的correlationId
标头聚合消息。标题在消息中标记了一些连续的子序列,即它在新的子序列开始时改变。聚合器的目的是将子序列转换为单独的“分组”消息
消息源是外部的且不可预测的,因此它无法使用sequenceSize
标头提供发出的消息。因此,在下一条消息带有另一个correlationId
标头之前,无法决定是否释放当前累积组(或者timeout
ms没有下一条消息,这意味着输入结束)。部分释放是不可接受的。
问题是Spring Integration ReleaseStrategy
旨在仅发布当前累积组(包括当前消息),而我的任务需要“向前看”查找当前组是否完成的下一条消息。从下一个消息的角度来看,同样的问题可能被视为“回顾”释放。
所以问题是:有没有办法根据下一条消息的标题(不包括后者)从聚合器中释放消息组?
我研究了org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler
的源代码,我目前发现的唯一解决方法是一个相当肮脏的技巧 - 我继承自AggregatingMessageHandler
并覆盖handleMessageInternal
方法。在方法中,我将当前消息的correlationId
与前一次调用中保存的消息进行比较。如果它不同,我从商店中提取以前的组并用它调用forceComplete
。然后(以任何方式)我将当前消息处理委托给父的handleMessageInternal
方法。这是代码片段:
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
Long currentGroupId = message.getHeaders().get(CORRELATION_ID, Long.class);
boolean needToReleasePreviousGroup = ((previousGroupId != null) && !previousGroupId.equals(currentGroupId));
if (needToReleasePreviousGroup) {
MessageGroup previousGroup = getMessageStore().getMessageGroup(previousGroupId);
if (previousGroup.size() != 0) {
forceComplete(previousGroup);
} else {
log.debug("Previous group with id={} has been already released. Skip.", previousGroupId);
}
}
super.handleMessageInternal(message);
previousGroupId = currentGroupId; // do unconditionally as we'll check that group on the next step anyway
}
我意识到这个解决方案使聚合器本身有状态(虽然它不应该是),并且不适用于许多其他场景。此外,它使应用的代码与框架的内部结合。
如果有人指出我提供更好的解决方案,我会很高兴的。我愿意提供有关问题或我使用的解决方案的其他详细信息。
答案 0 :(得分:1)
将single group
解决方案和您的说明视为:
'向前看'以查找下一条消息,以确定当前组是否已完成。
“当前”字是这里的关键。
所以,这对我来说意味着您的聚合器是correlationStrategy
,您必须根据当前消息的状态释放当前状态并启动一个新状态。
为此,我将聚合器真正地作为单个分组 - 1
应该返回一些常量,例如ReleaseStrategy
。
要发布或不发布当前组实际上是MessageGroup.getMessages()
责任。最新消息将是MessageGroupProcessor
中的最后一条消息。因此,您会收到该消息,决定是否需要发布,然后转到自定义MessageGroupProcessor
以生成聚合器的累积结果。
在<form #heroForm="ngForm" (ngSubmit)="add(newHero); heroForm.reset()">
<!-- place your input stuff here -->
<button type="submit" class="btn btn-default" [disabled]="!heroForm.valid">Add hero</button>
中你删除最新的“有罪”消息,不要将其包含在结果中,并将其发送回聚合器以形成新的消息组。
对你有意义吗?
答案 1 :(得分:0)
对于那些试图解决相同或类似问题的人,有一个Github gist包含基于接受的答案构建的聚合器配置的源代码。
针对该问题有意简化源代码。真正的一个还可以通过超时或组大小阈值来释放组。如果需要,也准备好分享它。