aws FIFO 队列返回空队列,即使它有可用的消息

Ang*_*Tim 5 fifo amazon-sqs node.js aws-lambda

我有一个超过 200 万条可用消息的 FIFO 队列。我想用 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();
Run Code Online (Sandbox Code Playgroud)

Den*_*iri 6

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

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

您的队列使用者收到接收消息 API 的空响应的原因是队列使用者在处理后没有删除接收到的消息。如果您的 FIFO 队列传递了其他消息,而未删除已传递的消息,则可能违反“先进先出传递”的保证。因为可以在处理第一条消息之前处理第二条消息。如果您考虑有多个队列使用者的情况,则此行为会变得更加明显。

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