Lambda 多次处理同一个 SNS 事件?

Lambda processing same SNS event multiple times?

我将 AWS Lambda 函数配置为处理来自单个主题的 SNS 事件。当该函数运行时,它可能会发出一些其他通知并调用 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,它似乎只是发布和交付一个,就像我预期的那样,所以这似乎是 Lambda 方面的问题。有谁知道事件可能像这样多次触发我的 lambda 的任何原因吗?

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

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

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

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

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

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 次重试之前

希望对您有所帮助