【问题标题】:aws FIFO queue returns empty queue even though it has messages availableaws FIFO 队列返回空队列,即使它有可用的消息
【发布时间】:2018-10-29 22:38:36
【问题描述】:

我有一个 FIFO 队列,有超过 2 百万条消息可用。 我想用 lambda 函数处理它们,但 10 次轮询消息中有 9 次得到队列为空的回复。这绝对不是真的。我试图更改为长轮询,但没有帮助。 这是我用于轮询消息的代码。

import { create as listenToSqsQueue } from "sqs-consumer";

listenToSqsQueue({
    queueUrl: Config.aws.sqsurl,

    handleMessage: async function (message, done){
        // do some work with `message`s
        Promise.resolve(invokePoller(functionName, message, callback));
        done();
      }
    ,         
    batchSize: 10
}).on("empty", function() {
    callback(undefined, "Queue is empty");
}).on("error", function(error: Error, message: any) {
    console.error(error, message);
    callback(error)
}).start();

【问题讨论】:

  • 有多少消息在发送中?通常,报告此类情况的人未能说明 SQS 在每个消息组中实施严格的排序。 No group without messages in flight 意味着现在没有消息可用,因为在这种情况下传递消息意味着传递无序。
  • @Michael-sqlbot 是的,你是对的,我错过了对于 FIFO 队列,具有相同 messageId 的消息将按顺序传递的观点。谢谢你的回答

标签: node.js aws-lambda amazon-sqs fifo


【解决方案1】:

我建议您按照以下步骤尝试一个小测试,以自己了解 FIFO 队列的这种行为。

  1. 为测试目的创建 FIFO 队列
  2. 向队列发送两条消息
  3. 调用队列的接收消息 API。您应该会收到您进入队列的第一条消息
  4. 多次调用接收消息 API,对于后续尝试,您会得到空响应。 30 秒后(可见性超时),如果您调用接收消息 API,您将收到相同的消息。但是,您将永远不会收到来自队列的第二条消息。
  5. 删除您在步骤 3 中收到的消息
  6. 调用接收消息 API,您应该会收到发送到队列的第二条消息

您的队列消费者收到接收消息 API 的空响应的原因是队列消费者在处理后没有删除收到的消息。如果您的 FIFO 队列在未删除已传递的消息时传递了其他消息,则可能违反 "First-In-First-Out Delivery" 的保证。因为可以在处理第一条消息之前处理第二条消息。如果考虑到有多个队列消费者的情况,这种行为会变得更加明显。

总而言之,我建议您考虑删除一条消息作为对 FIFO 队列的通知,以指示队列使用者已成功处理该消息,并且允许 FIFO 队列传递队列中的下一条消息。要修复客户端代码,您可以修改它以在成功处理后删除消息。

【讨论】:

    【解决方案2】:

    作为@Denis Weerasiri 提出的解决方案的替代解决方案,您可以为每条消息设置不同的消息组 ID,这样您就可以解决适用于同一组中消息的 FIFO 限制。

    请参阅 AWS 文档中的 Using the Amazon SQS message group ID

    【讨论】:

      猜你喜欢
      • 2017-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2019-11-07
      • 1970-01-01
      • 2018-09-26
      • 2020-11-27
      相关资源
      最近更新 更多