问题描述
如何配置可见性超时,以便可以再次读取 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 队列中删除”。