web-dev-qa-db-ja.com

AWS LambdaContainerの破棄イベント

ラムダで接続を解放してリソースをクリーンアップするタイミング。通常のNode JSアプリケーションでは、フックを使用します

process.on('exit', (code) => {
    console.log(`About to exit with code: ${code}`);
});

ただし、これはAWSLambdaでは機能しません。スリープモードでのMysql接続の結果。このようなアクティブな接続に十分なリソースがありません。 AWSのドキュメントには、これを実現する方法が指定されていません。

AWS Lambdaコンテナの停止イベントを受信するにはどうすればよいですか?

17

編集:簡単な答えは、コンテナがいつ停止したかを知るためのそのようなイベントはないということです。

中程度の答え:これについてAWSの誰かと話し合った後、データベース接続をモジュールレベルでスコープして、コンテナーが存在する限り再利用されるようにする必要があると思います。コンテナが破棄されると、その時点で接続が破棄されます。

元の答え:

この質問は、AWS Lambda関数で考慮すべきいくつかのかなり複雑な問題に触れています。これは主に、データベースへの接続プールまたは長期間有効な接続を検討する可能性があるためです。まず、Node.jsのLambda関数は、次のシグネチャを使用して、エクスポートされた単一のNode.js関数として実行されます(おそらくご存知のとおり)。

exports.handler = (event, context, callback) => {
    // TODO implement
    callback(null, 'Hello from Lambda');
};

データベース接続を処理する最もクリーンで簡単な方法は、関数を呼び出すたびにデータベース接続を作成および破棄することです。このシナリオでは、データベース接続は関数の最初に作成され、最後のコールバックが呼び出される前に破棄されます。このようなもの:

const mysql = require('mysql');

exports.handler = (event, context, callback) => {
  let connection = mysql.createConnection({
    Host     : 'localhost',
    user     : 'me',
    password : 'secret',
    database : 'my_db'
  });

  connection.connect();

  connection.query('SELECT 1 + 1 AS solution', (error, results, fields) => {
    if (error) {
      connection.end();
      callback(error);
    }
    else {
      let retval = results[0].solution;
      connection.end();
      console.log('The solution is: ', retval);
      callback(null, retval);
    }
  });
};

注:私はそのコードをテストしていません。私は議論のための例を提供しているだけです。

私はまた会話を見ました このように あなたの接続を主要な機能本体の外に置く可能性について議論します:

const mysql = require('mysql');

let connection = mysql.createConnection({
  Host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

exports.handler = (event, context, callback) => {
  // NOTE: should check if the connection is open first here
  connection.query('SELECT 1 + 1 AS solution', (error, results, fields) => {
    if (error) {
      callback(error);
    }
    else {
      let retval = results[0].solution;
      console.log('The solution is: ', retval);
      callback(null, retval);
    }
  });
};

ここでの理論は次のとおりです。AWSLambdaは関数の最初の呼び出し後に既存のコンテナを再利用しようとするため、次の関数呼び出しではすでにデータベース接続が開かれています。上記の例では、使用する前に開いている接続の存在を確認する必要がありますが、理解できます。

もちろん問題は、これにより接続が無期限に開いたままになることです。私はこのアプローチのファンではありませんが、特定の状況によってはこれが機能する場合があります。そのシナリオに接続プールを導入することもできます。ただし、この場合、接続またはプールを完全に破棄するイベントはありません。関数をホストしているコンテナプロセス自体が強制終了されます。したがって、ある時点でデータベースが接続を終了することを信頼する必要があります。

私はそれらの詳細のいくつかについて間違っているかもしれませんが、私はあなたが見ているものであると高いレベルで信じています。お役に立てば幸いです。

16
Todd Price