AWS Lambda RDS连接超时

我正在尝试使用连接到我的RDS数据库的Node.js编写一个Lambda函数。 数据库正在工作,可以从我的Elastic Beanstalk环境访问。 当我运行该函数时,它返回一个超时错误。

试图增加超时到5分钟,完全相同的结果。

经过一番研究,我得出的结论是,这可能是一个安全问题,但无法在亚马逊的文档或这个答案中find解决scheme(这是我能find的唯一的答案)。

以下是安全细节:

  • RDS和Lambda都在同一个安全组中。
  • RDS具有所有stream量入站和出站规则。
  • Lambda具有AmazonVPCFullAccess策略。

我的代码是:

'use strict'; console.log("Loading getContacts function"); var AWS = require('aws-sdk'); var mysql = require('mysql'); exports.handler = (event, context, callback) => { var connection = mysql.createConnection({ host : '...', user : '...', password : '...', port : 3306, database: 'ebdb', debug : false }); connection.connect(function(err) { if (err) callback(null, 'error ' +err); else callback(null, 'Success'); }); }; 

我得到的结果是:

 "errorMessage": "2017-03-05T05:57:46.851Z 9ae64c49-0168-11e7-b49a-a1e77ae6f56c Task timed out after 10.00 seconds" 

我要感谢所有帮助过我的人,这个问题与我想象中的不同。 由于某些原因,代码中的callback不起作用,即使它在AMAZON'S OWN DEFAULT SAMPLE中。

工作代码如下所示:

 'use strict'; console.log("Loading getContacts function"); var AWS = require('aws-sdk'); var mysql = require('mysql'); exports.handler = (event, context) => { var connection = mysql.createConnection({ host : '...', user : '...', password : '...', port : 3306, database: 'ebdb', debug : false }); connection.connect(function(err) { if (err) context.fail(); else context.succeed('Success'); }); }; 

虽然使用上下文将工作,你只需要添加context.callbackWaitsForEmptyEventLoop = false; 到处理程序,然后像这样正常使用callback:

 exports.handler = (event, context) => { context.callbackWaitsForEmptyEventLoop = false; var connection = mysql.createConnection({ //connection info }); connection.connect(function(err) { if (err) callback(err); else callback(null, 'Success'); }); }; 

答案在这里的文档(花了我几个小时find这个): http : //docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html

在“比较上下文和callback方法”一节中,有一个“重要”注释来解释事情。

在笔记底部写着:

因此,如果需要与上下文方法相同的行为,则必须将上下文对象属性callbackWaitsForEmptyEventLoop设置为false。

基本上,callback继续到事件循环的结尾,而不是结束事件循环的上下文。 所以设置callbackWaitsForEmptyEventLoop使callback像上下文一样工作。

我连接RDS时分享我的经验。

您需要为Lambda function启用VPC访问,在此期间您将为其分配安全组 。

然后,在分配给RDS实例的安全组内,您将为分配给Lambdafunction的安全组启用访问。

你可以在这里获得更多的信息

RDS和Lambda都在同一个安全组中。

这是关键。 默认情况下,同一个安全组内的通讯是不允许的。 而且你需要明确的允许它(Ex sg-xxxxx ALL TCP)。 这只会工作,如果你的lambda试图通过私人IP访问数据库。

如果它试图通过公共IP访问它,它将无法正常工作,并且您还需要为此添加必要的整体。

但有更好的办法:

  1. 为您的lambda创build单独的安全组
  2. 在RDS sg的端口3306允许入站stream量为lambdas sg。

这个问题并不是来自超时,而是来自你closures连接的方式。 使用.destroy()而不是等待callback,或者在closures.end(function(err) { //Now call your callback });的连接时正确使用callback.end(function(err) { //Now call your callback });

看到这个线程更深入的解释。