为什么我的 Amazon SQS FIFO 队列没有返回所有消息或其他消息组中的消息?

2 分钟阅读
0

当我调用 ReceiveMessage API 时,我的 Amazon Simple Queue Service(Amazon SQS)先进先出(FIFO)队列没有返回某些消息。

解决方案

使用 FIFO 队列时,您无法请求接收来自特定消息组 ID 的消息。您也无法过滤 ReceiveMessage API 调用,使其一次只能返回一个消息组中的消息。

当您在 ReceiveMessage API 调用中指定 MaxNumberOfMessages 参数时,SQS 会返回尽可能多的具有相同消息组 ID 的消息。ReceiveMessage API 调用还可以返回来自其他可用消息组的消息。

对于 FIFO 队列,当您收到属于特定消息组 ID 的消息时,请遵循以下准则:

  • 必须先删除当前消息组 ID 中的消息,然后才能接收同一消息组 ID 的更多消息。
  • 已收到但尚未删除的消息处于“传输”状态。处于“传输”状态的消息会阻止接收同一消息组的可用消息。
  • 导致消息处于“传输”状态的一个常见原因是消费者客户端意外失败。另一个原因是下游 AWS Lambda 消费者函数遇到异常或达到最大并发数。
  • ChangeMessageVisibility API 可以延长或缩短处于“传输”状态的消息的可见性超时期限。
  • 您可以等到消息可见性超时期限到期后再重新传送消息。

对于所有 FIFO 队列和 Amazon SQS 配额限制,请遵循以下指南:

  • FIFO 队列最多可以有 20,000 条处于“传输”状态的消息。
    **注意:**Amazon SQS 不会返回超过配额限制的错误消息。
  • 在不激活高吞吐量的情况下,FIFO 队列每秒最多可以处理 300 笔交易(TPS)。即使队列中有可用消息,超过 300 TPS 的请求也会出现“ThrottlingException”错误。
  • SQS FIFO 队列消息存储在分区中。每个分区支持最多 300 TPS 的发送、接收和删除操作。有关更多信息,请参阅Optimizing partition utilization
  • 具有高吞吐量的 FIFO 队列可以与多个消息组共享一个分区。如果某个分区上的某个消息组超过 300 TPS,则由于存在节流,来自该分区上其他消息组的消息将无法传送。
  • FIFO 队列高吞吐量的每秒交易数因 AWS 区域而异。有关更多信息,请参阅Quotas related to messages

要降低 FIFO 队列的 Amazon SQS 吞吐量限制,请遵循以下指南:

FIFO 队列会浏览前 20,000 条消息,以确定可用的消息组。如果前 20,000 条消息的消息组因为处于“传输”状态的消息而被阻止,则来自前 20,000 条消息以外的其他消息组的消息也不会返回。有关更多信息,请参阅Avoid having a large backlog of messages with the same group ID

示例 A

一个 FIFO 队列总共有 20,001 条消息。前 20,000 条消息属于消息组 1,最后一条消息属于消息组 2。当您尝试接收来自该队列的消息时,您只会收到来自组 1 的消息。任何连续的 ReceiveMessage API 调用都会接收到空消息。之所以发生这种情况,是因为 FIFO 只查看属于组 1 的消息,而当前调用屏蔽了该消息组。

示例 B

一个 FIFO 队列总共有 20,000 条消息。前 19,999 条消息属于消息组 1,最后一条消息属于消息组 2。当您尝试从队列接收消息时,第一个 ReceiveMessage 调用会收到一条属于组 1 的消息。第二个 ReceiveMessage 调用收到一条属于组 2 的消息。任何其他 ReceiveMessage 调用都会接收到空消息,因为这两个组都被当前调用屏蔽了。

相关信息

Amazon SQS FIFO (First-In-First-Out) queues

Using the Amazon SQS message group ID

AWS 官方
AWS 官方已更新 6 个月前