Amazon SQS 中的可见性超时不起作用

问题描述

如何配置可见性超时,以便可以再次读取 SQS 中的消息?

我将 Amazon SQS 作为消息队列。多个应用程序正在发送消息。我现在使用 Spring 侦听器读取队列中的消息,如下所示:

    public DefaultMessageListenerContainer jmsListenerContainer() {
        
        SQSConnectionFactory sqsConnectionFactory = SQSConnectionFactory.builder()  
                .withAWSCredentialsProvider(new DefaultAWSCredentialsProviderChain())
                .withEndpoint(environment.getProperty("aws_sqs_url"))
                .withAWSCredentialsProvider(awsCredentialsProvider)
                .withNumberOfMessagesToPrefetch(10).build();
        
        DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
        dmlc.setConnectionFactory(sqsConnectionFactory);
        dmlc.setDestinationName(environment.getProperty("aws_sqs_queue"));
        dmlc.setMessageListener(queueListener);
                
        return dmlc;
    }

queueListener 实现了 javax.jms.MessageListener,它进一步使用了 onMessage() 方法

我还配置了一个调度程序,在一段时间后再次读取队列。它使用 receiveMessage()com.amazonaws.services.sqs.AmazonSQS

一旦消息到达队列,侦听器就会读取消息。我想在一段时间后再次读取消息,即通过调度程序,但是一旦消息被侦听器读取,它就不会变得可见或再次读取。根据 Amazon 的 SQS 开发人员指南,认可见性超时为 30 秒,但该消息即使在 30 秒后也不可见。我曾尝试在 SQS QUEUE ParaMETER CONSOLE 中设置自定义可见性超时,但它不起作用。

有关信息,没有人从队列中删除消息。

解决方法

我只对 Amazon SQS 略为熟悉,但我可以说,通常在消息传递用例中,当消费者接收并确认该消息,然后该消息从队列。鉴于您的 Spring 应用程序正在接收该消息,我怀疑它也在确认该消息,因此将其从队列中删除,这会阻止您的调度程序稍后接收它。请注意,Spring 的 DefaultMessageListenerContainer 默认使用 JMS 的 AUTO_ACKNOWLEDGE 模式。

This documentation from Amazon 实质上表示,如果消息在 JMS 上下文中得到确认,则它会“从底层 Amazon SQS 队列中删除”。