【发布时间】:2019-01-09 10:44:17
【问题描述】:
我的递归 lambda 函数在使用计划的 AWS 事件调用时停止(也与 cron 作业选项一起使用)。如果我使用 lambda-dashboad 或无服务器框架进行调用 - 一切正常。 lambda 函数的持续时间超过 6 小时,当通过事件调用时,它会运行 15-30 分钟然后停止。如何调用 lambda 函数有区别吗?我在哪里可以找到这种行为的解释?
LAMBDA-METHOD -> invokeLambda(lambdaname, payload) { // eslint-disable-line class-methods-use-this
const req = {
FunctionName: lambdaname,
InvocationType: 'Event',
Payload: JSON.stringify(payload),
};
const lambda = new aws.Lambda({
region: 'us-east-1',
});
console.log(`[INFO - LAMBDA - ${lambdaname.toUpperCase()}] ${JSON.stringify(payload)}`);
return lambda.invoke(req).promise();
}
...
const createInstance = (Gapi, Parser, Lambda, Config) => {
const gapi = new Gapi(Config);
const parser = new Parser(gapi, Config);
return new Lambda(gapi, parser, Config);
};
...
exports.sync_contacts = async (event, context) => {
// create clear instance of class
const Lambda = createInstance(GAPI, PARSER, LAMBDA, CONFIG);
// util for handle 5min limit lambda :use context.getRemainingTimeInMillis()
const middleware = Ware();
// return result off work after 5 min (worked 4.5 min then give 0.5 for refresh)
const nextRefresh = await refresh(Lambda, middleware)(event, context);
if (typeof nextRefresh === 'string') return nextRefresh;
// recursive invoked
if (nextRefresh.type === 'REFRESH') {
return Lambda.invokeLambda(
context.functionName,
nextRefresh,
);
}
// recursive invoked
if (nextRefresh.type === 'DONE') {
Lambda.token = nextRefresh.token;
const [err, token] = await Lambda.tokenStep('NEXT');
if (err) return err;
if (token) {
return Lambda.invokeLambda(
context.functionName,
{ type: 'INIT', payload: { lastIndex: 0, token } },
);
}
}
// finish
return '[LAMBDA - GLOBAL - DONE]';
};
【问题讨论】:
-
我没有得到你的代码,因为你没有直接使用official sdk,但是实际上有3 different ways of calling a Lambda:一个是试运行(没有你需要的),第二个是其他在同步 (
RequestResponse) 或异步 (Event) 上有所不同。我不知道这是否可以解决您的问题,但您可以尝试一下,谁知道... -
顺便说一下,上限是 5 分钟(不是代码中提到的 3 分钟)。有一个名为getRemainingTimeInMillis() 的上下文方法可以让您有剩余的时间来更好地处理截止日期
-
我更正了代码中的cmets
-
您是否检查过 CloudWatch 中的日志?如果是,您可以在这里提供它以便我们与您一起调试吗?递归函数的问题是任何失败都会停止整个执行,它可能是内存不足(很常见)、执行时间过长、IAM角色没有所需的权限等。
-
另外,如果 Promise 仍处于挂起状态,默认调用回调(或在 AsyncFunction 中使用
return)可能不会停止 Lambda 执行。您可以通过设置context.callbackWaitsForEmptyEventLoop = false、more info here 来更改此行为。
标签: javascript node.js recursion aws-lambda