Java 当消息计数大于并发使用者数量时,如何使用Spring IntegrationFlow中所需的所有消息?

Java 当消息计数大于并发使用者数量时,如何使用Spring IntegrationFlow中所需的所有消息?,java,spring,spring-integration,spring-rabbit,spring-integration-amqp,Java,Spring,Spring Integration,Spring Rabbit,Spring Integration Amqp,我有一个定义如下的集成流: IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, "queueName") .id("id") .autoStartup(autoStartup) .concurrentConsumers(2) .maxConcurrentConsumer

我有一个定义如下的集成流:

IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, "queueName")
                    .id("id")
                    .autoStartup(autoStartup)
                    .concurrentConsumers(2)
                    .maxConcurrentConsumers(3)
                    .messageConverter(messageConverter()))
                    .aggregate(a -> a.correlationExpression("payload.entityId")
                                    .releaseExpression("size() eq iterator().next().payload.batchSize")
                                    .sendPartialResultOnExpiry(true)
                                    .groupTimeout(2000)
                                    .expireGroupsUponCompletion(true)
                                    .outputProcessor(myMessageGroupProcessor))
                    .handle(serviceActivatorBean, "myMethod", e -> e.advice(requestHandlerRetryAdviceForIntegrationFlow()))
                    .get();
其目的是将“批量”发送的多个相关消息分组。下面是一个例子:

// Message 1
{ "name": "Message1", 
  "entityId": "someId"
  "batchSize": 2,
  "batchIndex": 1, 
  .... }

// Message 2
{ "name": "Message2",
  "entityId": "someId"
  "batchSize": 2,
  "batchIndex": 2, 
  .... }
由于上述原因,我们使用手动确认RabbitMQ以避免丢失消息

集成流对于大小为2的批处理非常有效,但一旦一批处理中有2条以上的消息,我们就会遇到麻烦:

[my-service] 2017-12-04 17:46:07.966  INFO 1 --- [ask-scheduler-5] x.y.EntityUpdater : Will update entity [entitId] from messages: Message1, Message2 
[my-service] 2017-12-04 17:46:09.976  INFO 1 --- [ask-scheduler-3] x.y.EntityUpdater : Will update entity [entitId] from messages: Message3
请注意,记录的消息之间的时间大约为2秒(即我们确认为
groupTimeout

我怀疑这是因为Spring使用了2条消息(不是自动确认的),然后聚合等待第3条消息(因为在本例中,
batchSize
是3)。但是,由于只有两个并发使用者,因此此消息永远不会在2秒钟的窗口内被使用

concurrentConsumers
计数增加到3可解决此特定问题。问题是我们不知道我们收到的批次的大小,它们可能相当大,可能大小在50左右。这意味着仅仅增加
concurrentConsumers
是不可行的选择

春天处理这个问题的合适方法是什么?

正如我在

使用此模式时,
concurrency*prefetch
必须足够大,以包含所有未完成批处理的消息


出于这个原因,我不赞成使用该模式,除非您有相当可预测的数据。

谢谢,但您是否建议使用另一种模式来解决聚合+安全(即保证在崩溃时不会丢失消息)问题?如果是这样的话,我将非常感谢任何指向它的指针。如果您能确保
并发*预取
对于所有情况都足够大,您就可以了。如果你不能预测,你会陷入僵局。您可以通过使用组超时并拒绝丢弃的消息来处理此问题,以便重新传递这些消息。另一种方法是将持久消息存储与聚合器一起使用。