如果Java代码抛出runtimeException,Lambda函数不会重试sqs消息处理

问题描述 投票:0回答:2

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

根据lambda文档,如果lambda代码抛出runtimeException,那么lambda会在将它发送回队列之前重试相同的消息两次。但是,我没有看到这种行为。我只看到它只处理一次消息。

在这种情况下,这是相关lambda代码的片段。

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

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

}

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

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

aws-lambda amazon-sqs aws-java-sdk
2个回答
0
投票

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

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

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

请记住,在java代码中抛出运行时异常后,lambda会将消息发送回队列。根据sqs中的重新驱动设置,sqs将根据重新驱动号生成相同的事件。

一旦lambda无法成功处理重新驱动次数,消息将从主队列发送到DLQ


0
投票

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)。

enter image description here

这是Lambda函数的代码:

enter image description here

这是sqs-test的配置

enter image description here

这是重新启动政策

enter image description here

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

enter image description here

您必须缺少一些基本配置,因为它可以无缝地工作,如上图所示。

© www.soinside.com 2019 - 2024. All rights reserved.