我有一个基于DSL的流,它使用split
遍历对象列表并发出Kafka消息:
.transform(...)
.split()
.channel(KAFKA_OUT_CHANNEL)
发送完所有消息后,我需要致电服务,还需要记录已处理的消息数。
我了解一种方法是使用publishSubscribeChannel
,其中第一个subscribe
执行实际的Kafka发送,然后aggregate
执行服务调用:
.transform(...)
.split().
.publishSubscribeChannel(pubSub -> pubSub
.subscribe(f -> f.channel(KAFKA_OUT_CHANNEL)))
我在弄清楚如何使用DSL实际完成pubSubChannel中的.aggregate
部分时遇到了问题。到目前为止,我已经尝试过:
.subscribe(f -> f.channel(KAFKA_OUT_CHANNEL)
.subscribe(f -> f.aggregate(c -> c.processor( ?? ))))
有指针吗?
答案 0 :(得分:0)
AbstractMessageSplitter
默认有一个applySequence = true
:
/**
* Set the applySequence flag to the specified value. Defaults to true.
* @param applySequence true to apply sequence information.
*/
public void setApplySequence(boolean applySequence) {
我们在消息中包含以下标头:
if (this.applySequence) {
builder.pushSequenceDetails(correlationId, sequenceNumber, sequenceSize);
}
聚合器的默认关联策略实际上基于IntegrationMessageHeaderAccessor.CORRELATION_ID
标头。这样,它将具有相同correlationKey
的消息收集到相同的MessageGroup
中。默认ReleaseStrategy
基于MessageGroup
和该sequenceSize
标头比较。最后,默认的MessageGroupProcessor
仅将组中的所有消息收集为一条消息,并以Collection
作为有效负载。换句话说,聚合器的默认行为与拆分器完全相反。
我不知道您要从聚合器执行的输出,但是您不需要在此配置任何其他逻辑-相关性和释放逻辑应基于默认状态。
您可以在Reference Manual中找到足够的信息。
答案 1 :(得分:0)
这取决于聚合后想要的内容-如果您只想要有效负载列表,只需使用aggregate()
...
@SpringBootApplication
public class So51059703Application {
public static void main(String[] args) {
SpringApplication.run(So51059703Application.class, args);
}
@Bean
public ApplicationRunner runner(ApplicationContext context) {
return args -> {
context.getBean("flow.input", MessageChannel.class).send(new GenericMessage<>(
Arrays.asList("a", "b", "c")));
};
}
@Bean
public IntegrationFlow flow() {
return f -> f
.split()
.publishSubscribeChannel(p -> p
.subscribe(f1 -> f1.handle(System.out::println))
.subscribe(f2 -> f2
.aggregate()
.handle(System.out::println)));
}
}
如果您只想计数:
@SpringBootApplication
public class So51059703Application {
public static void main(String[] args) {
SpringApplication.run(So51059703Application.class, args);
}
@Bean
public ApplicationRunner runner(ApplicationContext context) {
return args -> {
context.getBean("flow.input", MessageChannel.class).send(new GenericMessage<>(
Arrays.asList("a", "b", "c")));
};
}
@Bean
public IntegrationFlow flow() {
return f -> f
.split()
.publishSubscribeChannel(p -> p
.subscribe(f1 -> f1.handle(System.out::println))
.subscribe(f2 -> f2
.aggregate(c -> c
.processor(processor(), "reduce"))
.handle(System.out::println)));
}
@Bean
public Object processor() {
return new Object() {
public int reduce(List<Message<?>> messages) {
return messages.size();
}
};
}
}