Spring boot Spring积分-散射聚集

Spring boot Spring积分-散射聚集,spring-boot,spring-integration,Spring Boot,Spring Integration,我使用SpringIntegration和ScatterGatherHandler()将3个并行请求(使用ExecutorChannel)发送到外部RESTAPI,并将它们的响应聚合到一条消息中 在聚合器的aggregatePayloads方法(AggregatingMessageHandler)中引发异常之前,一切正常。在这个场景中,错误消息被成功地传递到消息传递网关,该网关启动了流(调用者)。然而,ScatterGatherHandler线程仍然处于挂起状态,等待gatherer回复(我相信

我使用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。我将在代码中遵循这种方法。