【问题标题】:Serverless SQS consumer skips messages无服务器 SQS 消费者跳过消息
【发布时间】:2019-05-25 03:03:04
【问题描述】:

我正在使用无服务器框架来使用来自 SQS 的消息。发送到队列的某些消息不会被消耗。他们直接进入飞行中的 SQS 状态,然后从那里进入我的死信队列。当我查看消费者的日志时,我可以看到它消费并成功处理了 9/10 消息。一个总是不被消耗并最终进入死信队列。我将reservedConcurrency 设置为1,以便一次只能运行一个消费者。函数使用者 timeout 设置为 30 秒。这是消费者代码:

module.exports.mySQSConsumer = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;

  console.log(event.Records);

  await new Promise((res, rej) => {
    setTimeout(() => {
      res();
    }, 100);
  });

  console.log('DONE');

  return true;
}

消费者功能配置如下:

functions:
  mySQSConsumer:
    handler: handler.mySQSConsumer
    timeout: 30 # seconds
    reservedConcurrency: 1
    events:
      - sqs:
          arn: arn:aws:sqs:us-east-1:xyz:my-test-queue
          batchSize: 1
          enabled: true

如果我删除await 函数,它将处理所有消息。如果我将超时时间增加到 200 毫秒,更多的消息将直接进入飞行状态,然后从那里进入死信队列。这段代码非常简单。任何想法为什么它会跳过一些消息?使用第一个 console.log() 语句,未使用的消息甚至不会显示在日志中。他们似乎完全被忽略了。

【问题讨论】:

    标签: amazon-sqs serverless


    【解决方案1】:

    我发现了问题所在。 SQS 队列 Lambda 函数事件触发的工作方式与我想象的不同。消息被推送到 Lambda 函数中,而不是被它拉取。我认为这可以通过 AWS 更好地设计,但事实就是如此。

    问题在于 Default Visibility Timeout 设置为 30 秒,而 Reserved Concurrency 设置为 1。当 SQS 队列很快被数千条记录填满时,AWS 开始以如下速率将消息推送到 Lambda 函数比单个函数实例处理它们的速度更快。 AWS“假设”它可以简单地启动更多的 Lambda 实例来跟上背压。但是,并发限制不允许它启动更多实例 - Lambda 函数受到限制。因此,该函数开始将某些消息的失败返回到 AWS 后端,因此会将失败的消息隐藏 30 秒(默认设置),并在此时间段后将它们放回队列中以进行重新处理。由于单个实例要处理的记录太多,30 秒后,Lambda 函数仍然很忙,无法再次处理这些消息。因此情况会重演,消息会恢复为隐身状态 30 秒。总共重复3次。第三次尝试后,消息进入死信队列(我们以这种方式配置了 SQS 队列)。

    为解决此问题,我们将 Default Visibility Timeout 增加到 5 分钟。这足以让 Lambda 函数处理队列中的大部分消息,而失败的消息则以隐身状态等待。 5 分钟后,它们被推回队列,由于 Lambda 函数不再忙,它将处理其中的大部分。其中一些必须经过两次隐身才能成功处理。

    因此,解决此问题的方法是像我们一样增加Default Invisibility Timeout,或者在消息进入死信队列之前增加必要的失败次数。

    我希望这对某人有所帮助。

    【讨论】:

    • 天哪,你是救生员! SQS 文档在解释这一点方面做得非常糟糕。我就在这种情况下,我无法弄清楚为什么我的 lambda 会消耗队列中超出配置的 batchSize 的所有消息,然后将它们失败到死信队列。太感谢了。您应该将自己的答案标记为正确的答案。
    • 顺便说一句,您的回答让我看到了这篇博文,这也可能有助于其他人更好地理解这一点。 medium.com/@zaccharles/…
    • 很高兴你写了那篇文章。我本来打算自己做的,但你打败了我。
    猜你喜欢
    • 2019-06-10
    • 2018-08-29
    • 2023-02-17
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 2015-11-25
    • 2012-03-11
    相关资源
    最近更新 更多