我开始使用 AWS Lambda 执行一个非常简单的任务,即执行 SQL 查询以从 RDS postgres 数据库中检索记录并根据结果创建 SQS 消息。
因为亚马逊默认只提供aws-sdk
模块(使用 node 4.3 引擎),我们需要执行这个 SQL 查询,我们必须创建一个自定义部署包,其中包括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);
});
};
在测试我的 lambda 函数时,如果你查看 WatchLogs,函数本身运行大约需要 500 毫秒,但它说它实际上需要 30502.48 毫秒(参见屏幕截图)。
所以我猜解压缩我的 318KB 包并开始执行它需要 30 秒?这对我来说只是个玩笑还是我错过了什么?我尝试上传 zip 并将我的包上传到 S3 以检查它是否更快,但我仍然有相同的延迟。
我注意到 Python 版本可以在没有任何自定义打包的情况下本机执行 SQL 请求...
我们所有的应用程序都是用 node 编写的,所以我真的不想离开它,但是我很难理解为什么亚马逊没有为数据库交互提供基本的 npm 模块。
欢迎任何意见或帮助。在这一点上,如果需要 30 秒来运行每分钟触发的脚本,我不确定 Lambda 是否对我们有益......
有人面临同样的问题吗?
更新:这就是您不再需要时需要立即关闭连接的方式(再次感谢 Vitaly 的帮助):
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
[...]