首页 > 解决方案 > SNS 何时重试向 Lambda 发送消息,我可以强制吗?

问题描述

我已经像这样设置了一个 Lambda:

exports.handler = async (event) => {
  throw new Error('I AM SAD');
};

它可以由 SNS 主题和 API 网关调用。

我还设置了一个包含两个订阅的 SNS 主题;一个直接向 Lambda 发送消息(使用 Lamba 协议);另一个通过 API Gateway (HTTPS) 发送。我希望 SNS 在 lambda 失败时重试发送消息。但它似乎只能通过 API Gateway 工作。当直接调用 Lambda 时,SNS 只尝试一次(并报告 SUCCESS)。

我知道即使对于 SNS -> Lambda 也有某种重试策略,但是什么时候触发?对于 SNS -> HTTP,它似乎在收到 HTTP 错误代码时触发。

来自Amazon SNS 死信队列 - Amazon Simple Notification Service

当 Amazon SNS 具有过时的订阅元数据时,可能会发生客户端错误。当所有者删除终端节点(例如订阅 Amazon SNS 主题的 Lambda 函数)或所有者更改附加到订阅终端节点的策略以阻止 Amazon SNS 将消息传送到终端节点时,通常会发生这些错误。Amazon SNS 不会重试由于客户端错误而失败的消息传递。

失败的 lambda(如上所述)是否被视为客户端错误?我可以强制服务器端错误吗?

标签: amazon-web-servicesaws-lambdaamazon-sns

解决方案


Lambda 函数引发的异常不是客户端错误。这些是由于配置错误而不是功能代码中的异常而发生的。

SNS 只尝试一次(并报告成功)。

这是设计的。SNS 成功向 Lambda服务传递了一个请求,以使用您发布到 SNS 的消息负载异步调用您的 Lambda 函数。

当 SNS 调用 Lambda 函数时,它只会将该请求传递给 Lambda 服务一次。SNS 唯一会重试的情况是它无法联系 Lambda 服务,或者请求未经授权,如果 Lambda 或 SNS 内部或服务之间的中断阻止它们通信,或者权限不正确,就会发生这种情况。

Amazon SNS 使用包含消息和元数据的事件异步调用您的函数。

...

对于异步调用,Lambda 将消息排队并处理重试。如果 Amazon SNS 无法访问 Lambda 或消息被拒绝,Amazon SNS 会在几个小时内以增加的间隔重试。有关详细信息,请参阅 Amazon SNS 常见问题中的可靠性。

https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html

一旦调用请求被移交,SNS 就不再参与该事件。

重试失败调用的是 Lambda 服务。

一些 AWS 服务,例如 Amazon Simple Storage Service (Amazon S3) 和 Amazon Simple Notification Service (Amazon SNS),异步调用函数来处理事件。当您异步调用函数时,您无需等待函数代码的响应。您将事件交给 Lambda,然后 Lambda 处理其余的事情。您可以配置 Lambda 如何处理错误,并且可以将调用记录发送到下游资源以将应用程序的组件链接在一起。

https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html

默认情况下,您应该会看到日志表明 Lambda 总共调用了 3 次抛出异常的函数,在 1 分钟后重试,然后 2 分钟重试。


推荐阅读