AWS Lambda を使用して、SQL クエリを実行して RDS postgres データベースからレコードを取得し、結果に基づいて SQS メッセージ ベースを作成するという非常に単純なタスクを実行し始めました。
aws-sdk
デフォルトでは、Amazon はモジュール (ノード 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);
});
};
ラムダ関数をテストするとき、WatchLogs を見ると、関数自体の実行には約 500 ミリ秒かかりましたが、実際には 30502.48 ミリ秒かかったことが示されています (スクリーンショットを参照)。
318KB のパッケージを解凍して実行を開始するのに 30 秒かかると思いますか? それは私にとって単なる冗談ですか、それとも何か足りないのですか? zip をアップロードし、パッケージを S3 にアップロードして高速かどうかを確認しようとしましたが、それでもレイテンシーは同じです。
Python バージョンは、カスタム パッケージなしでネイティブに SQL リクエストを実行できることに気付きました...
私たちのアプリケーションはすべて node で書かれているので、そこから離れたくはありませんが、なぜ Amazon がデータベースの相互作用のための基本的な 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
[...]