Cognito在调用Lambda函数时返回UnexpectedLambdaException超时错误

时间:2017-08-29 14:21:45

标签: amazon-web-services lambda sequelize.js amazon-cognito

我第一次登录我的应用程序时,早上第一件事,AWS Cognito会返回此错误:

{
  "message": "arn:aws:lambda:us-east-1:XXXXXXXXXX:function:main-devryan-users_onCognitoLogin failed with error Socket timeout while invoking Lambda function.",
  "code": "UnexpectedLambdaException",
  "time": "2017-08-29T13:30:01.351Z",
  "requestId": "1c04c982-8cbe-11e7-b9c9-a584e55a17f8",
  "statusCode": 400,
  "retryable": false,
  "retryDelay": 96.636396268355
}

第二次,以及之后的其余时间,一切都很好。

当我在Cloudwatch中查看我的main-devryan-users_onCognitoLogin函数的日志时,它在2.3秒内成功完成:

REPORT RequestId: 1f2d5a22-8cbe-11e7-ba74-5b21665a40c1  Duration: 2283.60 ms    Billed Duration: 2300 ms Memory Size: 128 MB    Max Memory Used: 51 MB  

每次之后,在剩下的时间里,我都没有看到这个错误。我的Lambda在30秒后设置为超时,但我知道Cognito needs a response in 5 seconds

我的lambda函数只是更新数据库中的最后一次登录时间。它第一次变慢,因为创建与RDS DB的连接大约需要1.8秒。我正在使用Node JS 6和Sequelize 3进行该部分。

我猜测Lambda将我的应用加载到容器中需要2.7秒。

有人在这里有解决方案吗?我很难过。

2 个答案:

答案 0 :(得分:2)

这似乎是一个lambda冷启动时间问题。您可以尝试各种方法来优化它,例如:

  1. 增加分配给您的功能的内存,这也会按比例增加CPU。由于您的功能很少被调用,因此增加内存大小的额外成本将通过更快的冷启动时间来平衡,从而缩短计费时间。

  2. 减少代码大小:更小的.zip,删除Node.js中不必要的require()等。例如,如果要包含Async库只是为了删除嵌套回调,请考虑放弃提高绩效。

答案 1 :(得分:0)

我通过创建2个Lambdas来解决了这个问题:onLoginactualOnLoginonLogin Lambda只是异步启动actualOnLogin Lambda并立即返回。 actualOnLogin我的数据库更新。这种方式onLogin以< 100ms的速度返回,Cognito很高兴。

这里是onLogin的基本代码:

let AWS = require("aws-sdk");
let lambda = new AWS.Lambda();

let params = {
    FunctionName: "main-@deploy_env@-users_actualCognitoLogin", // I'm using the Serverless framework
    InvocationType: "Event", // Makes it async
    LogType: "None",
    Payload: JSON.stringify(event)
};

lambda.invoke(params, (err, data) => {
    if (err) {
        console.log("ERROR: " + err, err.stack); // an error occurred
        context.done(err, event);
    } else {
        console.log(data); // successful response
        context.done(null, event);
    }
});