amazon-web-services - 为什么 SqS 消息有时会保留在队列中

标签 amazon-web-services amazon-sqs

我以非常简单的方式使用 Amazon SQS 队列。通常,消息被写入并立即可见和读取。有时,会写入一条消息,并在队列中保留运行中(不可见)几分钟。我可以从控制台看到它。接收消息等待时间为 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 ..”的日志行永远不会出现,这导致我进入控制台并查看该消息是否存在,事实确实如此。

最佳答案

听起来您误解了您所看到的内容。

“正在传输”的消息不是待传递的消息,它们是已经传递但消费者没有进一步采取行动的消息。

Messages are considered to be in flight if they have been sent to a client but have not yet been deleted or have not yet reached the end of their visibility window.

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

当消费者收到一条消息时,它必须在某个时刻删除该消息,或者向 increase the timeout 发送请求。对于该消息;否则,超时后该消息将再次可见。如果消费者未能执行其中一项操作,该消息将自动再次可见。可见性超时是消费者在必须完成其中一件事情之前的时间。

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

Messages displayed in the console will not be available to other applications until the console stops polling for messages.

当控制台从“查看/删除消息”屏幕观察队列时,控制台中显示的消息“正在运行”。

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

关于amazon-web-services - 为什么 SqS 消息有时会保留在队列中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19792881/

相关文章:

ruby - Amazon SQS 优先级队列

node.js - AWS lambda从CloudFormation读取参数或输出

node.js - SST开始 "TypeError: getAwsCredentials is not a function"

java - Amazon S3 - 使用 Java AWS SDK 将区域设置为 EU

amazon-web-services - Cassandra 集群,想要跨一些数据中心进行复制,但不是全部

amazon-web-services - 使用 AWS CDK 捆绑 lambda docker 而不是 esbuild/debian WSL2

amazon-web-services - 如何使用cloudformation迁移sns和sqs?

amazon-web-services - Amazon SQS DLQ:是否将早于14天的sqs消息移至DLQ

Nginx 位于 AWS 弹性负载均衡器之前?

python - 使用 boto3,如何检查 AWS IAM 用户是否有密码?