75

我以一种非常简单的方式使用 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;
}

发生这种情况时,“read ..”的日志行永远不会出现,它是导致我进入控制台并查看消息是否存在的原因,它确实存在。

4

2 回答 2

113

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

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

如果消息已发送给客户端但尚未删除或尚未到达其可见性窗口的末尾,则认为消息正在传输中。

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

当消费者收到一条消息时,它必须——在某个时候——要么删除这条消息,要么发送一个请求以增加该消息的超时时间;否则,消息在超时到期后再次可见。如果消费者未能执行这些操作之一,则消息会自动再次变为可见。可见性超时是消费者在必须完成这些事情之一之前有多长时间。

消息不应该在没有收到消息的情况下处于“飞行中”——但是“某些东西”可以包括控制台本身,正如您在选择“查看/删除消息”时看到的弹出窗口中所指出的那样控制台(除非您已经选中“不再显示”复选框):

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

当控制台从“查看/删除消息”屏幕观察队列时,控制台中显示的消息处于“飞行状态”。

没有明显意义的部分是如果您的默认可见性超时仅为 5 秒并且您的代码中没有任何内容会增加该超时,则消息会“持续几分钟”飞行......但是......这几乎可以完美地解释为您的消费者没有正确处理消息,导致消息超时并立即重新传递,给人的印象是消息的单个实例仍在进行中,而实际上,消息正在短暂地转换回可见状态,只是几乎立即被另一名消费者认领,并再次将其带回飞行中。

于 2013-11-05T23:19:04.447 回答
1

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

要摆脱这些问题,您需要等待更多时间,以便队列有更多时间给出适当的结果。

于 2013-11-06T09:31:51.783 回答