Spring 从sqs fifo队列获取消息后,按相同顺序执行消息

Spring 从sqs fifo队列获取消息后,按相同顺序执行消息,spring,amazon-web-services,spring-boot,spring-cloud,spring-messaging,Spring,Amazon Web Services,Spring Boot,Spring Cloud,Spring Messaging,我正在定义一个类似于下面定义的消息侦听器。这些消息是查询语句。消息按顺序推送到队列中,这样在推送到表中时就不会违反任何外键规则。当我将maxnumberofmessages设置为10时,我发现查询的执行顺序似乎不正确。但是,当我将其设置为1时,我看不到任何问题。当我将maxnumberofmessages设置为大于1的值时,如何确保以与队列中相同的顺序读取消息 @Bean public SimpleMessageListenerContainer simpleMessageListenerCon

我正在定义一个类似于下面定义的消息侦听器。这些消息是查询语句。消息按顺序推送到队列中,这样在推送到表中时就不会违反任何外键规则。当我将maxnumberofmessages设置为10时,我发现查询的执行顺序似乎不正确。但是,当我将其设置为1时,我看不到任何问题。当我将maxnumberofmessages设置为大于1的值时,如何确保以与队列中相同的顺序读取消息

@Bean
public SimpleMessageListenerContainer simpleMessageListenerContainer(AmazonSQSAsync amazonSQSAsync) {
    SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
    simpleMessageListenerContainer.setAmazonSqs);
    simpleMessageListenerContainer.setMessageHandler(queueMessageHandler());
    simpleMessageListenerContainer.setMaxNumberOfMessages(10);
    return simpleMessageListenerContainer;
}


@SqsListener(value = "${sqs.url}", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void onMessage(String serviceData, @Header("MessageId") String messageId, @Header("ApproximateFirstReceiveTimestamp") String approximateFirstReceiveTimestamp) {
    repository.execute(serviceData);

}
修改代码

@Bean
public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory() {
    SimpleMessageListenerContainerFactory msgListenerContainerFactory = new SimpleMessageListenerContainerFactory();
    msgListenerContainerFactory.setAmazonSqs(amazonSQSAsyncClient());
    msgListenerContainerFactory.setAutoStartup(false);
    msgListenerContainerFactory.setMaxNumberOfMessages(10);
    msgListenerContainerFactory.setTaskExecutor(threadPoolTaskExecutor());
    return msgListenerContainerFactory;
}


@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(1);
    executor.setMaxPoolSize(1);
    executor.setThreadNamePrefix("queueExecutor");
    executor.initialize();
    return executor;
}

@SqsListener(value = "${sqs.url}", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void onMessage(String serviceData, @Header("MessageId") String messageId, @Header("ApproximateFirstReceiveTimestamp") String approximateFirstReceiveTimestamp) {
    repository.execute(serviceData);

}

这是因为逻辑是这样的:

   ReceiveMessageResult receiveMessageResult = getAmazonSqs().receiveMessage(this.queueAttributes.getReceiveMessageRequest());
   CountDownLatch messageBatchLatch = new CountDownLatch(receiveMessageResult.getMessages().size());
   for (Message message : receiveMessageResult.getMessages()) {
        if (isQueueRunning()) {
             MessageExecutor messageExecutor = new MessageExecutor(this.logicalQueueName, message, this.queueAttributes);
             getTaskExecutor().execute(new SignalExecutingRunnable(messageBatchLatch, messageExecutor));
        } else {
            messageBatchLatch.countDown();
        }
  }
请注意
getTaskExecutor().execute()
。这就是您的消息被转移到自己的线程执行的方式


您可以考虑将其重新配置为<代码> TracePoLoTaskExcExpor <代码>,池大小为<代码> 1 < /代码>。您的所有消息都将在同一线程上处理,因此将提供订单。

谢谢@Artem Bilan。我发布的代码发生了什么变化?它正在创建多个线程吗?正确,默认的
ThreadPoolTaskExecutor
实际上是基于
maxNumberOfMessages
。所以,你有10个线程并行。太棒了。非常感谢。我还有一个问题。isQueueRunning()意味着什么?我假设这些是spring库,使用spring可以实现同样的功能吗?