Spring boot Spring积分-散射聚集
我使用SpringIntegration和ScatterGatherHandler()将3个并行请求(使用ExecutorChannel)发送到外部RESTAPI,并将它们的响应聚合到一条消息中 在聚合器的aggregatePayloads方法(AggregatingMessageHandler)中引发异常之前,一切正常。在这个场景中,错误消息被成功地传递到消息传递网关,该网关启动了流(调用者)。然而,ScatterGatherHandler线程仍然处于挂起状态,等待gatherer回复(我相信),由于其中的异常,该回复从未到达。也就是说,每次顺序调用都会使另外一个线程处于“卡住”状态,最终线程池会耗尽可用的工作线程 我当前的散射-聚集配置:Spring boot Spring积分-散射聚集,spring-boot,spring-integration,Spring Boot,Spring Integration,我使用SpringIntegration和ScatterGatherHandler()将3个并行请求(使用ExecutorChannel)发送到外部RESTAPI,并将它们的响应聚合到一条消息中 在聚合器的aggregatePayloads方法(AggregatingMessageHandler)中引发异常之前,一切正常。在这个场景中,错误消息被成功地传递到消息传递网关,该网关启动了流(调用者)。然而,ScatterGatherHandler线程仍然处于挂起状态,等待gatherer回复(我相信
@Bean
public MessageHandler distributor() {
RecipientListRouter router = new RecipientListRouter();
router.setChannels(Arrays.asList(Channel1(asyncExecutor()),Channel2(asyncExecutor()),Channel3(asyncExecutor())));
return router;
}
@Bean
public MessageHandler gatherer() {
AggregatingMessageHandler aggregatingMessageHandler = new AggregatingMessageHandler(
new TransactionAggregator(),
new SimpleMessageStore(),
new HeaderAttributeCorrelationStrategy("correlationID"),
new ExpressionEvaluatingReleaseStrategy("size() == 3"));
aggregatingMessageHandler.setExpireGroupsUponCompletion( true );
return aggregatingMessageHandler;
}
@Bean
@ServiceActivator(inputChannel = "validationOutputChannel")
public MessageHandler scatterGatherDistribution() {
ScatterGatherHandler handler = new ScatterGatherHandler(distributor(), gatherer());
handler.setErrorChannelName("scatterGatherErrorChannel");
return handler;
}
@Bean("taskExecutor")
@Primary
public TaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsyncThread-");
executor.initialize();
return executor;
}
到目前为止,我找到的唯一解决方案是为ScatterGatherHandler添加RequiresReply和GatherTimeout值,如下所示:
handler.setGatherTimeout(120000L);
handler.setRequiresReply(true);
这将产生一个异常,并在指定的超时值和聚合器的异常传递到消息传递网关之后,将ScatterGatherHandler的线程释放到pull。我可以在日志中看到以下消息:
[AsyncThread-1] [WARN] [o.s.m.c.GenericMessagingTemplate$TemporaryReplyChannel:] [{}] - Reply message received but the receiving thread has already received a reply: ErrorMessage
有没有其他方法可以做到这一点?我的主要目标是确保在聚合器的aggregatePayloads方法中引发异常时不会阻塞任何线程
谢谢。从技术上讲,这确实是一种预期行为。见文件: 在这种情况下,必须为ScatterGatherHandler配置合理、有限的
gatherTimeout
。否则,默认情况下,它将永远被阻止,等待gatherer的回复
真的没有办法打破人们对
封锁队列的期望。从ScatterGatherHandler
代码中获取()
。谢谢你的确认,Artem。我将在代码中遵循这种方法。