【问题标题】:Lambda processing same SNS event multiple times?Lambda 多次处理相同的 SNS 事件?
【发布时间】:2016-10-01 09:49:25
【问题描述】:

我有一个配置为处理来自单个主题的 SNS 事件的 AWS Lambda 函数。当函数运行时,它可能会发送一些其他通知并调用 context.succeed,如果发生错误,则调用 context.fail。 问题是同一个 SNS 事件似乎多次调用 Lambda。查看我看到的 CloudWatch 日志

START RequestId: cd7afdf8-2816-11e6-bca2-6f2e3027c5e1 Version: $LATEST

最终结束

END RequestId: cd7afdf8-2816-11e6-bca2-6f2e3027c5e1 REPORT RequestId: cd7afdf8-2816-11e6-bca2-6f2e3027c5e1 ...

紧跟在同一个日志中的开头是完全相同的 RequestID

START RequestId: cd7afdf8-2816-11e6-bca2-6f2e3027c5e1 Version: $LATEST

在发送此 SNS 事件的主题中查看 CloudWatch,它似乎只是 Publishing and Delivering only one,就像我预期的那样,所以这似乎是一个 Lambda 方面的问题。有谁知道某个事件可能会像这样多次触发我的 lambda 的任何原因?

编辑:我注意到这似乎发生在 lambda 接收失败时。我没有在 lambda 上看到任何类型的重试配置,并且不希望它默认以这种方式运行。

【问题讨论】:

  • 你说多次的时候,是2次还是3次?

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


【解决方案1】:

来自 Amazon lambda 常见问题页面 https://aws.amazon.com/lambda/faqs/

问:如果我的 Lambda 函数在处理事件期间失败会怎样?

在失败时,同步调用的 Lambda 函数将响应异常。异步调用的 Lambda 函数至少重试 3 次,之后该事件可能会被拒绝。重试来自 Amazon Kinesis 流和 Amazon DynamoDB 流的事件,直到 Lambda 函数成功或数据过期。 Kinesis 和 DynamoDB Streams 将数据保留 24 小时。

【讨论】:

  • 这个答案在技术上是正确的,但似乎并不直接适用。 Lambda 函数可以通过 SNS 直接调用,而不是使用 HTTP。
  • 感谢您找到此内容。这似乎是正在发生的事情。不幸的是,这弄乱了我已有的一些报告,因此即使我认为消息失败,我最终也可能不得不将调用称为成功。
  • 非常感谢跟踪这个细节 - 我有事件规则(cron 样式)被触发了 3 次......最初的超时,接下来的两个成功。所以“至少重试 3 次”似乎意味着“至少尝试了 3 次”。
  • 我的 lambda 在执行 99% 的代码后超时,因此日志看起来是合法的。增加 lambda 超时修复了我的重复 :-)
【解决方案2】:

我在 lambda cron 作业函数中遇到了类似的问题。我需要向运行几秒钟的服务/api发送请求,然后它才能返回第一个字节/响应(不需要响应处理),所以我的修复如下:

exports.handler = (event, context, callback) => {
// TODO implement

var https = require("https");
token = "xxxxxxxx";

var options = {
    host: "api.xxxxx.com",
    path: "/manage/cronjob/video",
    method: "GET",
    headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer "+token
    }
};

var req = https.request(options);
req.write("");
req.end();

//add timeout for context.done()
setTimeout(function(){
    context.done();
    callback(null, 'Hello from Lambda');
},1000); //This timeout should be lower than the lambda's timeout };

在这个例子中,我们有一个显式的回调来强制 lambda 退出,在函数出现超时错误并触发另外 2 次重试之前

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2020-06-14
    • 2010-09-28
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多