我正在尝试使用Spring与DSL和lambda实现以下内容:
收到消息后,将其发送给N
个消费者(通过publish-subscribe
)。等待有限的时间并返回在该时间间隔内从消费者(<= N
)到达的所有结果。
这是我到目前为止的示例配置:
@Configuration
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public class ExampleConfiguration {
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedRate(1000).maxMessagesPerPoll(1).get();
}
@Bean
public MessageChannel publishSubscribeChannel() {
return MessageChannels.publishSubscribe(splitterExecutorService()).applySequence(true).get();
}
@Bean
public ThreadPoolTaskExecutor splitterExecutorService() {
final ThreadPoolTaskExecutor executorService = new ThreadPoolTaskExecutor();
executorService.setCorePoolSize(3);
executorService.setMaxPoolSize(10);
return executorService;
}
@Bean
public DirectChannel errorChannel() {
return new DirectChannel();
}
@Bean
public DirectChannel requestChannel() {
return new DirectChannel();
}
@Bean
public DirectChannel channel1() {
return new DirectChannel();
}
@Bean
public DirectChannel channel2() {
return new DirectChannel();
}
@Bean
public DirectChannel collectorChannel() {
return new DirectChannel();
}
@Bean
public TransformerChannel1 transformerChannel1() {
return new TransformerChannel1();
}
@Bean
public TransformerChannel2 transformerChannel2() {
return new TransformerChannel2();
}
@Bean
public IntegrationFlow errorFlow() {
return IntegrationFlows.from(errorChannel())
.handle(m -> System.err.println("[" + Thread.currentThread().getName() + "] " + m.getPayload()))
.get();
}
@Bean
public IntegrationFlow channel1Flow() {
return IntegrationFlows.from(publishSubscribeChannel())
.transform("1: "::concat)
.transform(transformerChannel1())
.channel(collectorChannel())
.get();
}
@Bean
public IntegrationFlow channel2Flow() {
return IntegrationFlows.from(publishSubscribeChannel())
.transform("2: "::concat)
.transform(transformerChannel2())
.channel(collectorChannel())
.get();
}
@Bean
public IntegrationFlow splitterFlow() {
return IntegrationFlows.from(requestChannel())
.channel(publishSubscribeChannel())
.get();
}
@Bean
public IntegrationFlow collectorFlow() {
return IntegrationFlows.from(collectorChannel())
.resequence(r -> r.releasePartialSequences(true),
null)
.aggregate(a ->
a.sendPartialResultOnExpiry(true)
.groupTimeout(500)
, null)
.get();
}
}
TransformerChannel1
和TransformerChannel2
是示例消费者,只是在睡眠时实施,以模拟延迟。
消息流是:
splitterFlow -> channel1Flow \
-> channel2Flow / -> collectorFlow
一切似乎都按预期工作,但我看到警告如:
收到回复邮件但收到的帖子已收到回复
这是预期的,因为返回了部分结果。
问题:
errorChannel
,但我不确定在何处指定它。答案 0 :(得分:0)
是的,解决方案看起来不错。我想它适合Scatter-Gather
模式。从版本4.1
开始提供实现。
从另一方面来看,aggregator
还有更多选项,因为该版本也是expire-groups-upon-timeout
,默认情况下聚合器为true
。使用此选项false
,您将能够实现丢弃所有这些延迟消息的要求。不幸的是DSL并不支持yet。因此,即使您将项目升级为使用Spring Integration 4.1,它也无法提供帮助。
接收到的那些&#34;回复消息的另一个选项但是接收线程已经收到回复&#34;在spring.integraton.messagingTemplate.throwExceptionOnLateReply = true
选项中,使用jar中spring.integration.properties
内的META-INF
文件。
无论如何,我认为Scatter-Gather
是用例的最佳解决方案。
您可以在JavaConfig中找到here如何配置它。
<强>更新强>
异常和错误频道怎么样?
由于您已与throwExceptionOnLateReply
达成交易,我猜您通过requestChannel
向@MessagingGateway
发送消息。最后一个有errorChannel
选项。另一方面,PublishSubscribeChannel
有errorHandler
选项,您可以MessagePublishingErrorHandler
使用errorChannel
作为默认选项。
errorChannel
提供endpoint
bean和LoggingHandler
。errorChannel
。所以,请考虑,如果你真的需要覆盖那些东西。默认PublishSubscribeChannel
为{{1}},因此您只需添加自己的订阅者即可。