为什么AWS Lambda执行时间长,使用pg-promise

我开始使用AWS Lambda执行一个非常简单的任务,即执行SQL查询以从RDS postgres数据库检索logging,并在结果上创buildSQS消息库。

因为Amazon默认只提供aws-sdk模块(使用node 4.3引擎),所以我们需要执行这个SQL查询,所以我们必须创build一个包含pg-promise的自定义部署包。 这是我正在使用的代码:

 console.info('Loading the modules...'); var aws = require('aws-sdk'); var sqs = new aws.SQS(); var config = { db: { username: '[DB_USERNAME]', password: '[DB_PASSWORD]', host: '[DB_HOST]', port: '[DB_PORT]', database: '[DB_NAME]' } }; var pgp = require('pg-promise')({}); var cn = `postgres://${config.db.username}:${config.db.password}@${config.db.host}:${config.db.port}/${config.db.database}`; if (!db) { console.info('Connecting to the database...'); var db = pgp(cn); } else { console.info('Re-use database connection...'); } console.log('loading the lambda function...'); exports.handler = function(event, context, callback) { var now = new Date(); console.log('Current time: ' + now.toISOString()); // Select auction that need to updated var query = [ 'SELECT *', 'FROM "users"', 'WHERE "users"."registrationDate"<=${now}', 'AND "users"."status"=1', ].join(' '); console.info('Executing SQL query: ' + query); db.many(query, { status: 2, now: now.toISOString() }).then(function(data) { var ids = []; data.forEach(function(auction) { ids.push(auction.id); }); if (ids.length == 0) { callback(null, 'No user to update'); } else { var sqsMessage = { MessageBody: JSON.stringify({ action: 'USERS_UPDATE', data: ids}), /* required */ QueueUrl: '[SQS_USER_QUEUE]', /* required */ }; console.log('Sending SQS Message...', sqsMessage); sqs.sendMessage(sqsMessage, function(err, sqsResponse) { console.info('SQS message sent!'); if (err) { callback(err); } else { callback(null, ids.length + ' users were affected. SQS Message created:' + sqsResponse.MessageId); } }); } }).catch(function(error) { callback(error); }); }; 

当testing我的lambda函数时,如果你看看WatchLogs,函数本身需要花费大约500ms的时间才能运行,但实际上花费了30502.48 ms(参见截图)。

在这里输入图像说明 在这里输入图像说明

所以我猜这是需要30秒,解压缩我的318KB包,并开始执行它? 这对我来说只是一个笑话,还是我错过了什么? 我试着上传zip文件,同时也把我的软件包上传到S3,检查是否更快,但是我仍然有相同的延迟。

我注意到,Python版本可以本地执行SQ​​L请求,而无需任何自定义打包。

我们所有的应用程序都是用节点编写的,所以我不想离开它,但是我很难理解为什么Amazon没有为数据库交互提供基本的npm模块。

任何意见或帮助,欢迎。 在这一点上,我不确定如果运行每分钟触发的脚本需要30秒,Lambda会对我们有好处。

任何人都面临同样的问题?


更新 :这是你需要closures连接,只要你不再需要它(再次感谢维塔利他的帮助):

 exports.handler = function(event, context, callback) { [...] db.many(query, { status: 2, now: now.toISOString() }).then(function(data) { pgp.end(); // <-- This is important to close the connection directly after the request [...] 

执行时间应根据正在执行的操作的长度来衡量,而不是应用程序退出需要多长时间。

有很多图书馆使用连接池的forms。 这些通常在可configuration的不活动时间段之后终止。

如果pg-promise依次使用node-postgres , 则不活动时间由参数poolIdleTimeout确定,缺省值为30秒。 有了pg-promise,你可以通过pgp.pg.defaults.poolIdleTimeout来访问它。

如果您希望在最后一个查询执行后退出进程,则需要通过调用pgp.end()来closures连接池。 有关详细信息,请参见图书馆取消初始化

在大部分代码示例中也显示了这些,因为那些需要在完成之后立即退出。