我有一个用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日志,它只包含来自第一次处理的日志,而不是重试日志。
有人能告诉我,我在这里错过了什么,因为它没有按预期工作。
您缺少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
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:
您必须缺少一些基本配置,因为它可以无缝地工作,如上图所示。