AWS Lambda 容器销毁事件

问题描述 投票:0回答:2

什么时候释放lambda中的连接和清理资源。在普通的 Node JS 应用程序中,我们确实使用钩子

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

但是这在 AWS Lambda 上不起作用。导致Mysql连接处于睡眠模式。我们没有足够的资源来进行此类活动连接。 AWS 文档均未指定实现此目的的方法。

如何接收AWS Lambda容器的停止事件?

node.js containers aws-lambda serverless-framework
2个回答
23
投票

简短的回答是,没有这样的事件可以知道容器何时停止。

更新:我没有使用过这个库,但是https://www.npmjs.com/package/serverless-mysql似乎试图解决这个问题。

之前的长答案:

中等答案:在与 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);
    }
  });
};

这里的理论是这样的:因为 AWS Lambda 将在第一次调用函数后尝试重用现有容器,所以下一个函数调用将已经打开数据库连接。上面的示例可能应该在使用之前检查打开的连接是否存在,但您明白了。

问题当然是这会让你的连接无限期地打开。我不喜欢这种方法,但根据您的具体情况,这可能会起作用。您还可以在该场景中引入连接池。但无论如何,在这种情况下,您没有任何事件可以彻底销毁连接或池。托管您的函数的容器进程本身将被终止。因此,您必须依赖数据库在某个时刻终止连接。

我对其中一些细节可能是错误的,但我相信在较高的层面上这就是你所看到的。希望有帮助!


0
投票

我相信 Lambda 扩展提供了一种捕获终结逻辑的方法。这是一个讨论此选项的Stack Overflow Answer。它指向 AWS 文档的这部分。据推测,您可以在完成回调中关闭数据库连接。

我对此很好奇,因为它似乎是一种更干净的关闭方法,但我还没有测试过。

© www.soinside.com 2019 - 2024. All rights reserved.