如果使用 WaitTimeSeconds = 0 调用,AWS SQS ReceiveMessageAsync 不会收到消息

AWS SQS ReceiveMessageAsync not get messages if called with WaitTimeSeconds = 0

我有 EventBridge 将消息推送到 SQS,还有后台进程使用的 SQS 消息。

在后台进程中,我正在使用以下代码(延迟 1 秒执行):

var receiveMessageRequest = new ReceiveMessageRequest()
{
    QueueUrl = await GetQueueUrl(),
    WaitTimeSeconds = 0, // this is problematic line
    MaxNumberOfMessages = 1
};
var response = await _sqsClient.ReceiveMessageAsync(receiveMessageRequest);

场景是我向 EventBridge 发送 1 条消息,它被路由到 SQS。

如果我用 WaitTimeSeconds = 0 轮询队列,有时会在 20-40 秒后收到消息(奇怪地对应于 SQS 的 Default visibility timeout = 30,但不确定)。

但是,如果我用 WaitTimeSeconds = 1 调用此函数,那么它会按预期工作,这意味着消息接收速度很快。

我疯狂的假设是:看起来如果队列中有1条消息,并且使用了短轮询,由于某种原因它是不可见的。

根据 documentation

您看到这种行为是因为短轮询与长轮询。引用文档

With short polling, the ReceiveMessage request queries only a subset of the servers (based on a weighted random distribution) to find messages that are available to include in the response. Amazon SQS sends the response right away, even if the query found no messages.

With long polling, the ReceiveMessage request queries all of the servers for messages. Amazon SQS sends a response after it collects at least one available message, up to the maximum number of messages specified in the request. Amazon SQS sends an empty response only if the polling wait time expires.

并且在文档的底部通过设置 **WaitTimeSeconds** var

解释了短轮询 的行为

Short polling occurs when the WaitTimeSeconds parameter of a ReceiveMessage request is set to 0 in one of two ways:

  • The ReceiveMessage call sets WaitTimeSeconds to 0.
  • The ReceiveMessage call doesn’t set WaitTimeSeconds, but the queue attribute ReceiveMessageWaitTimeSeconds is set to 0.