【问题标题】:AWS SQS and Lambda Function : How to fail a lambda function and force message back on to queueAWS SQS 和 Lambda 函数:如何使 lambda 函数失败并强制消息返回队列
【发布时间】:2021-12-01 09:05:48
【问题描述】:

我们有一个 Lambda 事件源,它轮询 SQS 的消息并将它们传递给 Lambda 函数。

SQS 有一个Visibility Timeout,它指示消费者 (lambda) 在多长时间内收到一条消息,如果未成功完成,它将重新出现在队列中。

Lambda 函数有没有办法在我们检测到错误后立即强制执行此操作?

例如,假设 Lambda 有 10 分钟的超时。 SQS Visibility Timeout 需要更长。

但如果 Lambda 函数提前检测到问题并抛出错误 - 这将导致消息失败,但我们必须等待 SQS Visibility Timeout 消息可供其他消费者重试。

有没有办法让 Lambda 函数告诉 SQS 消息已失败并且应该立即返回队列?

【问题讨论】:

    标签: amazon-web-services aws-lambda amazon-sqs


    【解决方案1】:

    如果您使用的是内置 AWS Lambda SQS 集成,那么只需抛出异常(从 Lambda 函数返回非成功状态)将导致该调用的 event 中的所有 SQS 消息被立即放回队列中。

    来自the documentation

    当 Lambda 读取一个批次时,消息保留在队列中,但变为 隐藏队列的可见性超时长度。如果你的 函数成功处理批处理,Lambda 删除消息 从队列中。如果您的函数受到限制,则返回错误,或者 没有响应,消息再次变为可见。一个中的所有消息 失败的批量返回队列,所以你的函数代码必须能够 多次处理同一条消息而不会产生副作用。

    【讨论】:

    • 是的,我是,但我在抛出错误时它不会变得可见。它位于“飞行中”列表中,直到可见性超时触发。除非我没有正确地提出错误——我只是抛出一个 JS 错误,然后 Lambda 将其记录为未捕获的错误,所以我认为这是正确的......
    • 这听起来不正确。你能显示你的代码吗?或者至少是您抛出错误的部分,以及您如何从 Lambda 函数返回最终响应?
    • 您可以创建另一个 SQS 使其成为原始 SQS 的“DLQ”,如果没有人消费它,消息就会去那里。 docs.aws.amazon.com/AWSSimpleQueueService/latest/…
    • 所以,为了测试,如果payload包含error字段,它会抛出一个标准的JSErrorif(data.error) { throw new Error('Fail lambda:' + data.error); }。返回是一个简单的对象return { data:{ ... } }。但我假设抛出错误会阻止返回运行?
    • 请编辑您的原始问题以显示整个代码。
    【解决方案2】:

    调用ChangeMessageVisibility API 并将每条失败消息的可见性超时设置为 0 秒。然后抛出异常。

    如果您收到一批 SQS 消息并且能够成功处理其中一些消息,则从底层 SQS 队列中显式删除这些(成功)消息,然后将每个剩余失败消息的可见性超时设置为 0 秒,然后抛出异常。

    将消息的可见性超时设置为 0 terminates the visibility timeout for that message 并使该消息立即对其他消费者可见。

    【讨论】:

    • 我确实看过这个 - 但由于某种原因无法从 Lambda 函数中获取 SDK 进行身份验证 - 但无论哪种方式 - 这是否在该消息的生命周期内将超时设置为 0 ?因此,如果将其设置为 0,它将被添加回队列,然后由消费者收集,但是它会立即超时,因为它的 0,然后再次被收集,不是吗?或者一旦它被设置回队列,它会回到默认超时吗?
    • 它恢复到队列的可见性超时设置。您的 IAM 角色有什么问题阻止您使用 SQS API?
    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 2019-06-21
    • 2019-05-14
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 2021-10-03
    • 2021-05-14
    相关资源
    最近更新 更多