每当存在数据库调用时,AWS Lambda函数都会导致超时

时间:2019-05-17 11:55:17

标签: node.js amazon-web-services aws-lambda sequelize.js amazon-rds

我有一个带有一些AWS Lambda函数的API网关,这些函数可以进行数据库调用(使用sequelize.js),并将结果作为JSON对象返回。

当我在本地运行代码时,我得到了结果,但是当我部署代码时,其中有数据库调用的任何方法都将导致内部服务器错误。

以下代码返回消息:

module.exports.testFunction = (event, context, callback) => {
    return callback(null, {
        statusCode: 200,
        body: JSON.stringify({
            message: 'Test function is working.'
        })
    });
};

以下代码将数据库结果记录在CloudWatch中,但是API调用在6秒后超时,然后返回内部服务器错误(502):

module.exports.getAll = (event, context, callback) => {
    Entity.findAll().then(result => {
        console.log(JSON.stringify(result));
        return callback(null, {
            statusCode: 200,
            body: JSON.stringify(result)
        });
    });
};

有什么解决办法可以使退货有效吗?

3 个答案:

答案 0 :(得分:3)

首先,恭喜您能够成功识别问题。但是,可以从发生的问题中学到许多概念。让我们讨论其中的几个。

Lambda冷启动问题

要了解lambda中的冷启动概念,在不了解AWS Lambda的工作原理的情况下不可避免地要走得更远。请参考下面的链接,该链接解释了 AWS re:Invent 2018

中共享的lambda的整体工作

AWS Lambda在后台(视频链接):https://www.youtube.com/watch?v=QdzV04T_kec

回到冷启动问题,因为我们的lambda函数在容器中执行,如果在不活动的15分钟内没有进一步的函数调用,则执行后容器将被杀死。一旦容器被杀死,将来要执行相同功能的任何调用都将需要设置一个新容器,该过程可能需要5秒钟以上的时间(最可能的原因是api调用在6秒钟后终止)。但是,有许多可用选项可以使您的lambda保持温暖。请参考Serverless社区下面提到的链接。

使Lambda函数保持温暖(博客链接):https://serverless.com/blog/keep-your-lambdas-warm/

增加Lambda超时时间

“我必须进入AWS控制台并将超时增加到20秒”。


尽管这种方法是完全可以接受的,但是由于您使用的是较少服务器技术(显式serverless.yml文件),因此您可以直接更改默认的lambda超时时间(6秒)。请参考下面提到的代码段和链接以进一步了解。

provider:
 name: was
 runtime: nodejs6.10
 memorySize: 512 # optional, in MB, default is 1024
 timeout: 10 # optional, in seconds, default is 6

无服务器AWS Lambda功能指南(博客链接):https://serverless.com/framework/docs/providers/aws/guide/functions/

答案 1 :(得分:1)

我修复了它。我必须进入AWS控制台并将超时增加到20秒。因此,lambda函数可以运行,但是需要很长时间才能运行。现在,Amazon Support建议使用X-Ray跟踪来查看哪些呼叫需要很长时间。

答案 2 :(得分:0)

添加另一个答案,因为我发现了实际的问题。

将超时设置为20可以正常工作,但是每次通话大约需要10秒,而不仅仅是冷启动。但是,仅几毫秒后就已经收到查询结果。

显然,AWS Lambda传递了一个context argument in handler functions,其属性之一是callbackWaitsForEmptyEventLoop,其默认值为true:

  

callbackWaitsForEmptyEventLoop –设置为false以在执行回调时立即发送响应,而不是等待Node.js事件循环为空。如果为false,则任何未完成的事件将在下一次调用期间继续运行。

我在函数开始时将该属性设置为false,现在每次调用只需要70毫秒。

module.exports.getAll = (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;
    Entity.findAll().then(result => {
        console.log(JSON.stringify(result));
        return callback(null, {
            statusCode: 200,
            body: JSON.stringify(result)
        });
    });
};