【问题标题】:Lambda function does not retry the sqs message processing in case the Java code throws a runtimeException如果 Java 代码抛出 runtimeException,Lambda 函数不会重试 sqs 消息处理
【发布时间】:2019-08-19 14:51:57
【问题描述】:

我有一个用 java 编写的 lambda 函数,它监听 sqs 事件并尝试对这些 sqs 消息进行某种处理。

根据 lambda 文档,如果 lambda 代码引发 runtimeException,则 lambda 将重试同一消息两次,然后再将其发送回队列。但是,我看不到这种行为。 我只看到它只处理一次消息。

在这种情况下,这是来自相关 lambda 代码的 sn-p。

@Override
    public Boolean handleRequest(SQSEvent sqsEvent, Context context) {

          try{
               ........some queue message processing.....
          }
          catch(Exception ex){
               throw new RuntimeException("exception occurred");
          }

}

这是否不足以让 lambda 再重试消息 2 次?我确实检查了 cloudwatch 以查看 lambda 日志,它仅包含来自第一次处理的日志,而不是重试的日志。

谁能告诉我我在这里错过了什么,因为它没有按预期工作。

【问题讨论】:

    标签: aws-lambda amazon-sqs aws-java-sdk


    【解决方案1】:

    您缺少 handleRequest 中的 throws 子句。如果你没有那个,lambda 只会吞下异常

    public Boolean handleRequest(SQSEvent sqsEvent, Context context) throws RuntimeException
    

    除此之外,Thales Munussi 告诉你的关于同步轮询的内容是绝对正确的。当您将 sqs 与 lambda 挂钩时,lambda 会轮询 sqs,从而保持两者之间的开放连接,从而使其成为同步连接 根据 aws 文档,lambda 在这种同步情况下不会重试。在 sqs 本身设置一个 dlq 并退休是你最好的办法

    请记住,在您的 java 代码中引发运行时异常后,lambda 会将消息发送回队列 根据您的 sqs 中的 redrive 设置,sqs 将根据 redrive 编号生成相同的事件。

    一旦 lambda 无法成功处理 redrive 次数,消息就会从主队列发送到 DLQ

    【讨论】:

      【解决方案2】:

      documentation 表示如果调用是异步,它会再重试两次。 SQS 是一个基于投票的系统。 Lambda 将轮询队列,它的所有调用都将是同步

      对于基于轮询的 AWS 服务(Amazon Kinesis、Amazon DynamoDB、Amazon Simple Queue Service),AWS Lambda 轮询流或消息队列 并同步调用您的 Lambda 函数。

      您可以在源 SQS 队列上配置一个 DLQ,以防您的消息失败,以便您可以进一步分析它或根据您配置的逻辑再次处理该消息。

      编辑

      OP 无法以某种方式查看 DLQ 中的消息。我附上了图片来证明它是有效的。

      Lambda sqs-test 由 SQS 队列 sqs-test 中的新消息触发

      这些是队列(sqs-test-dlq 被配置为 sqs-test 的 DLQ)。

      这是 Lambda 函数的代码:

      这是sqs-test的配置

      这是重新驱动政策

      消息在 Lambda 函数中失败后,成功发送到配置的 DLQ:

      您一定缺少一些基本配置,因为它可以无缝运行,如上图所示。

      【讨论】:

      • 它的配置方式,lambda 配置了 sqs 并监听 sqs 事件。在那种情况下,我认为它是异步调用,不是吗?
      • 不,它是同步的。在幕后,它仍然是一种轮询机制
      • “这由 Amazon Simple Queue Service 组成。如果您将 Amazon SQS 队列配置为事件源,AWS Lambda 将轮询队列中的一批记录并调用您的 Lambda 函数。”
      • 我相信轮询机制只会告诉 lamda 消息已准备好,而 lamda 仍在异步获取消息。这不正确吗?
      • 无论如何,当我抛出 runtimeException 时,它甚至不会进入 DLQ。我看到 sqs 只是丢失了消息,以防 lambda 遇到运行时异常,该异常也从未进入 DLQ
      猜你喜欢
      • 1970-01-01
      • 2021-10-18
      • 2021-10-03
      • 2021-04-25
      • 1970-01-01
      • 2018-03-10
      • 2019-02-02
      • 2018-08-03
      • 1970-01-01
      相关资源
      最近更新 更多