将消息添加到SQS队列中并将其配置为触发lambda函数(nodejs)时。
当触发lambda函数时-我可能想在5分钟后重试相同的消息,而不从队列中删除该消息。如果Lambda无法连接外部主机(例如API),我想这样做的原因-我想在5分钟后仅尝试3次再试一次。
如何用node js编写?
例如在Laravel中,我们可以使用Specifying Max Job Attempts
功能。使用public $tries = 5;
来源:https://laravel.com/docs/5.7/queues#max-job-attempts-and-timeout
我们如何在node.js中做类似的事情?
我正在考虑将消息添加到另一个队列(以重试)。 Lambda函数会在5分钟后读取该队列中的所有消息,然后将该消息发送回主队列,这将触发Lambda函数。
答案 0 :(得分:4)
重试和重试“超时”都可以直接在SQS队列中进行配置。
创建队列时,请设置以下属性:
默认可见性超时是您的应用收到消息后,消息将被隐藏的时间。如果消息在lambda运行期间失败,并引发异常,则lambda 不会删除该批处理中的任何消息,并且最终所有这些消息都会重新出现在队列中。
如果您只想尝试3次,则必须设置SQS重新驱动策略(又称为“死信队列”)
重新驱动策略将使您的队列在消息N
重新出现在队列N
中多次之后将消息重定向到死信队列(DLQ),其中Message Retention Period
是介于1到1000之间的数字。
必须理解lambda将继续处理失败的消息(在代码中生成异常的消息),直到:
$group = "NewUsers"
Get-ADUser -SearchBase 'cn=users,dc=costco,dc=com' -Filter { whenCreated -ge $When } | %{ Add-ADGroupMember -Identity $Group -Members $_.samaccountname }
过期(SQS删除邮件)否则Lambda不会处理此错误消息。
基于几次实验,我了解了SQS集成的行为(重试中的documentation是模棱两可的ATM),lambda不会删除失败的消息并将继续重试它们。即使已设置Lambda DLQ,消息也不会发送到DLQ,它完全依赖于lambda DLQ documentation中所述的SQS队列的配置。
推荐
:正如我之前所说,如果在处理消息时代码中有异常,则将重试整批消息,某些消息是否正确处理并不重要。如果由于某种原因下游服务失败,您最终可能会看到在DLQ中处理的消息。
推荐
:博客文章“ Lambda Concurrency Limits and SQS Triggers Don’t Mix Well (Sometimes)”描述了如何在并发限制设置得太低的情况下,lambda导致大量邮件被限制,接收尝试从未增加过正在处理。
推荐
:该帖子和亚马逊的建议是:
- 将队列的可见性超时设置为您在功能上配置的超时的至少6倍。
- 如果函数在处理前一批批处理时限制了函数执行,则多余的时间允许Lambda重试。
- 将队列的重新驱动策略上的maxReceiveCount设置为至少5。这将有助于避免由于节流而将消息发送到死信队列。
- 配置死信以将失败的消息保留足够长的时间,以便稍后可以将其移回以进行重新处理
答案 1 :(得分:3)
这是我的方法。
(Q1 / Q2)SQS触发器-> Lambda L1(如果失败,请在(Q1 / Q2)上删除,然后放下 它在第二季度)->在失败DLQ上
当消息到达Q1时,如果从那里成功,它将触发Lambda L1。如果失败,则将其放到Q2(这是一个延迟的队列)。第二季度到达的每条消息都会有5分钟的延迟。
如果您的初始消息可能会延迟5分钟,那么您可能不需要两个队列。一个队列应该很好。如果初始延迟不可接受,则需要两个队列。拥有两个队列的另一个原因是,您将始终有一种方法来获取路径中出现的新消息。
如果在处理Q1 / Q2时遇到代码故障,则AWS基础结构将立即重试3次,然后再将其发送到DLQ1。如果您处理了代码中的错误,则可以使管道与您提到的时间一起使用。
SQS延迟队列:
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html
SQS Lambda体系结构:
答案 2 :(得分:2)
非常简单,无需进行任何编码。首先:如果您的代码将引发错误,AWS Lambda将重试3次以上以执行您的代码。在这种情况下,如果无法访问外部API,则AWS会在第三次重试时进行很大的更改–该API可以使用。再加上重试之间的延迟是随机的,这意味着重试之间存在延迟。
如果最糟糕的情况发生了,并且外部API尚未启动,则可以利用每个lambda所具有的死信队列(DLQ)功能。这将向SQS推送一条消息,指出出了什么问题,因此您可以采取其他措施。在这种情况下,请继续重试,直到成功。
您可以在此处了解更多信息:https://docs.aws.amazon.com/lambda/latest/dg/dlq.html
答案 3 :(得分:1)
根据此博客:
https://www.lucidchart.com/blog/cloud/5-reasons-why-sqs-lambda-triggers-are-a-big-deal
利用现有的重试逻辑和死信队列。如果lambda 函数未返回成功,消息不会从中删除 队列,并且在可见性超时到期后会重新出现。