您好我们正在尝试通过利用apache camel或spring integration来流式处理流程金融市场数据来计算交易信号。 我们的一个用例是根据价格时间戳汇总连续价格如下:
输入消息以时间序列中的(时间戳,价格)对形式出现。假设值为,每对(TX,PX)为消息,T为时间戳,P为价格值
(T0,P1),(T1,P1),(T2,P2),(T3,P3),(T4,P4)...
假设我们需要将每3个连续的消息聚合在一起进行进一步的计算,给定输入消息我们需要生成以下组,每个3对组是一个聚合消息:
[(T0,P1),(T1,P1),(T2,P2)],
[(T1,P1),(T2,P2),(T3,P3)],
[(T2,P2),(T3,P3),(T4,P4)],
....
正如您所看到的,大多数邮件将汇总到多个组。有人可以建议是否有办法通过使用当前聚合器而不用编写一个。
Spring集成聚合分组似乎也基于相关键,因此消息需要映射到一组相关键。但是,当前的api似乎只允许我们生成一个相关键,这意味着每条消息只能聚合到一个组。是否有任何解决方法。
P.S。
看完骆驼的源代码后,骆驼似乎无法支持我们的要求。试试春天的运气吧。 手指交叉 camel question答案 0 :(得分:1)
我们没有任何开箱即用的东西,但通过对SimpleMessageStore
的小修改,我能够做到你想要的。我已发布完整的RollingMessageStore
in a gist。
最重要的是修改removeGroup
以仅删除第一条消息,而不删除整个组。另外,让completeGroup
成为无操作。
设置expreGroupOnCompletion
以强制聚合器“移除”该组(通过调用修改后的removeGroup()
方法。
以下是SimpleMessageGroup
和RollingMessageGroup
...
182,184c190,194
<
< groupUpperBound.release(groupIdToMessageGroup.get(groupId).size());
< groupIdToMessageGroup.remove(groupId);
---
> Message<?> message = this.groupIdToMessageGroup.get(groupId).getOne();
> if (message != null) {
> this.groupUpperBound.release(1);
> this.removeMessageFromGroup(groupId, message);
> }
(另外删除completeGroup()
中的所有代码。
和测试案例......
@Test
public void testRolling() {
AggregatingMessageHandler aggregator = new AggregatingMessageHandler(new MultiplyingProcessor(), new RollingMessageStore());
aggregator.setExpireGroupsUponCompletion(true);
aggregator.setReleaseStrategy(new ReleaseStrategy() {
@Override
public boolean canRelease(MessageGroup group) {
return group.size() == 3;
}
});
QueueChannel replyChannel = new QueueChannel();
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
Message<?> message4 = createMessage(9, "ABC", 3, 3, replyChannel, null);
Message<?> message5 = createMessage(11, "ABC", 3, 3, replyChannel, null);
aggregator.handleMessage(message1);
aggregator.handleMessage(message2);
aggregator.handleMessage(message3);
aggregator.handleMessage(message4);
aggregator.handleMessage(message5);
Message<?> reply = replyChannel.receive(10000);
assertNotNull(reply);
assertEquals(reply.getPayload(), 105);
reply = replyChannel.receive(10000);
assertNotNull(reply);
assertEquals(reply.getPayload(), 315);
reply = replyChannel.receive(10000);
assertNotNull(reply);
assertEquals(reply.getPayload(), 693);
}
请继续打开JIRA New Feature Issue我们会考虑将这个(或更通用的解决方案)添加到即将发布的3.0版本中。
使用correlation-strategy-expression="'foo'"
和
release-strategy-expression=size()==3
。