Lambda如何处理同一个SNS事件被多次触发的情况?

7
我有一个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 在CloudWatch中查看发送此SNS事件的主题时,似乎只发布和传递了一个事件,正如我所期望的那样,因此这似乎是一个Lambda端的问题。是否有人知道事件可能触发我的lambda多次的任何原因?
编辑:我注意到当lambda收到失败时,似乎会发生这种情况。我没有看到任何重试配置,并且不希望默认情况下出现这种情况。

当你说多次时,是指2次还是3次? - Prasad Paravatha
2个回答

12

来自Amazon Lambda FAQs页面 https://aws.amazon.com/lambda/faqs/

问:如果我的Lambda函数在处理事件期间失败会发生什么?

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


2
这个答案在技术上是正确的,但似乎不直接适用。Lambda函数可以通过SNS直接调用,而不使用HTTP。 - Michael - sqlbot
谢谢你找到这个。看起来就是这样。不幸的是,这可能会影响我之前设定好的一些报告,所以即使在我原本认为的消息失败的情况下,我可能最终还是要称呼这个调用成功。 - Squirrel
非常感谢您追踪到这个细节 - 我有事件规则(cron样式)被触发了三次...最初的超时,接下来的两次成功。因此,“至少重试3次”似乎意味着“尝试了至少3次”。 - keen
我的 lambda 函数在执行了大约 99% 的代码后就超时了,所以日志看起来很真实。增加 lambda 超时时间解决了重复问题 :-) - Blundell

4

我曾经遇到与 Lambda 定时任务函数类似的问题。我需要发送请求到一个需要几秒钟才能返回第一个字节/响应(无需响应处理)的服务/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 退出,在函数出现超时错误并触发另外两次重试之前。希望能对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接