为什么 SqS 消息有时会保持在队列上的正在传输中

我正在以一种非常简单的方式使用 Amazon SQS 队列。通常,消息被写入并立即可见和读取。偶尔,会写入一条消息,并在队列中保留 In-Flight (Not Visible)几分钟。我在控制台上就能看到。接收消息-等待时间为0,默认可见性为5秒。它将保持这种状态几分钟,或者直到写入新消息并以某种方式释放它为止。几秒钟的延迟是可以的,但是超过60秒就不行了。

有8个读线程,总是轮询很长,所以不是有什么东西不想读它,而是它们。

编辑 : 需要说明的是,没有任何使用者读操作返回任何消息,无论控制台是否打开,都会发生这种情况。在这个场景中,只涉及到一条消息,而且它就在消费者不可见的队列中。

有人见过这种行为吗? 我可以做些什么来改善它?

下面是我正在使用的 java 的 sdk:

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.5.2</version>
</dependency>

下面是进行读取的代码(max = 10,maxwait = 0启动配置) :

void read(MessageConsumer consumer) {


List<Message> messages = read(max, maxWait);


for (Message message : messages) {
if (tryConsume(consumer, message)) {
delete(message.getReceiptHandle());
}
}
}


private List<Message> read(int max, int maxWait) {


AmazonSQS sqs = getClient();
ReceiveMessageRequest rq = new ReceiveMessageRequest(queueUrl);
rq.setMaxNumberOfMessages(max);
rq.setWaitTimeSeconds(maxWait);
List<Message> messages = sqs.receiveMessage(rq).getMessages();


if (messages.size() > 0) {
LOG.info("read {} messages from SQS queue",messages.size());
}


return messages;
}

“读取”的日志行。."当这种情况发生的时候从来不会出现,这就是导致我进入控制台并查看消息是否存在的原因,它确实存在。

102670 次浏览

听起来你好像误解了你所看到的。

“正在传输中”的消息并不等待传递,它们是已经传递但消费者没有进一步操作的消息。

如果消息已经发送到客户端,但尚未删除或尚未达到其可见窗口的末尾,则认为它们处于传输中。

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html

当使用者接收到消息时,它必须在某个时刻删除该消息,或者为该消息向 增加超时时间发送请求; 否则超时过期后消息将再次可见。如果使用者未能完成这些任务之一,则消息将自动再次可见。可见性超时是指在必须完成这些事情之一之前使用者有多长时间。

消息不应该是“在飞行中”没有东西已经收到他们-但是“东西”可以包括控制台本身,因为你会看到弹出式窗口,当你选择“查看/删除消息”在控制台(除非你已经选中了“不要显示这一次”复选框) :

在控制台停止对消息的轮询之前,其他应用程序将无法使用控制台中显示的消息。

当控制台从“ View/Delete Messages”屏幕上观察队列时,显示在控制台中的消息“处于飞行状态”。

如果默认的可见性超时只有5秒,而代码中没有任何东西增加了超时,那么消息在飞行中“飞行了几分钟”就没有明显的意义了... ... 然而... ... 消费者没有正确处理消息,导致消息超时并立即重新发送,给人留下消息的一个实例仍然在飞行中的印象,而实际上,消息正在短暂地过渡到可见,只是几乎立即被另一个消费者认领,再次返回到飞行中。

当您发送或锁定一条消息并在几秒钟内尝试获取新的消息列表时,可能会发生这种情况。AmazonSQS 将数据存储在多个服务器和多个数据中心 http://aws.amazon.com/sqs/faqs/#How_reliably_is_my_data_stored_in_Amazon_SQS中。

为了消除这些问题,您需要等待更多的时间,以便队列有更多的时间来提供适当的结果。