这不是问题,而是更多的问题,但是,以前有人遇到过吗?有人知道如何预防吗?
我有一个lambda函数(L1),它调用了所有用NodeJs编写的第二个lambda函数(L2)(运行时:Node.Js 8.10,而aws-sdk
应该是v2.488.0-但我只是粘贴文档中的内容)。简而言之,L1应该调用L2,并且当L2执行两次时!我通过将日志写入CloudWatch发现了这一点,并且可以看到一个L1日志和两个L2日志。
这是L1和L2的简化版本。
L1:
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
module.exports = {
handler: async (event, context, callback) => {
const lambdaParams = {
FunctionName: 'L2',
Qualifier: `dev`,
Payload: JSON.stringify({}),
};
console.log(`Calling: ${JSON.stringify(lambdaParams)}`);
return await lambda.invoke(lambdaParams).promise();
},
};
L2:
module.exports = {
handler: async (event, context, callback) => {
console.log(`L2 called`);
},
};
在CloudWatch中,我可以看到一个Calling ....
和两个L2 called
!
顺便说一句,这并非一直发生。这是步骤函数过程的一部分,该过程将调用L1 10k次。我的代码以这样的方式编写:如果L2执行两次(每个调用一次),它将使整个过程失败(因为L2仅在记录不存在时才向DB插入记录,而在记录不存在时会失败)。到目前为止,我设法记录了3次此行为。他们所有人都处理相同的10k项,每次都面对不同迭代的问题。
有人有同样的经历吗?甚至更好的是,知道如何确保一个调用导致一个执行?
答案 0 :(得分:2)
使用10K lambda调用时,它肯定遇到故障并重试。
异步调用– Lambda重试两次函数错误。如果 函数没有足够的能力来处理所有传入的请求, 事件可能要在队列中等待数小时或数天才能发送到 功能。您可以在函数上配置死信队列以 捕获未成功处理的事件。欲了解更多 有关信息,请参阅异步调用。
如果这是正在发生的事情,并且您设置了死信队列,您将能够隔离故障事件。
您还可以使用CloudWatch Logs Insights轻松快速地搜索lambda的错误消息。选择日志组后,此查询将帮助您入门。只需更改时间窗口即可。
fields @timestamp, @message
| filter @message like /(?i)(Exception|error|fail|5\d\d)/
| sort @timestamp desc
| limit 20
答案 1 :(得分:2)
您的lambda函数必须是幂等的,因为在不同情况下可以调用两次。
https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/
https://cloudonaut.io/your-lambda-function-might-execute-twice-deal-with-it/
答案 2 :(得分:0)
可能导致这种情况的一种情况是,在您的L2 lambda中您没有返回任何东西,这将导致L1 lambda(调用方)认为L2存在错误,因此触发了Retry机制。尝试返回L2中的内容,甚至只是简单地单击“确定”。