node.js - AWS Lambda 容器销毁事件

标签 node.js containers aws-lambda serverless-framework

何时释放 lambda 中的连接和清理资源。在普通的 Node JS 应用程序中,我们确实使用了钩子(Hook)

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

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

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

最佳答案

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

更新:我没有使用过这个库,但是 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);
    }
  });
};

注意:我还没有测试过该代码。我只是提供一个讨论的例子。

我还看到了对话 like this one讨论将连接置于主函数体之外的可能性:

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 在第一次调用您的函数后会尝试重用现有容器,所以下一次函数调用将已经打开了一个数据库连接。上面的示例可能应该在使用之前检查是否存在打开的连接,但您明白了。

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

我可能对其中一些细节有误,但我相信从高层次上讲,这就是您所看到的。希望对您有所帮助!

关于node.js - AWS Lambda 容器销毁事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45234813/

相关文章:

amazon-web-services - 如何从 AWS SAM 本地 docker 实例连接到主机 MySQL?

javascript - 将参数传递给返回链中的 Promise 的函数

javascript - 如何为 passportjs 使用 jquery/ajax 数据

c++ - 池容器的最佳数据结构是什么?

c++ - 动态控制c++数据结构中的成员数量

css - 按钮不进入div?

javascript - NodeJS 模块 - 填充数组变成空对象。为什么?

node.js - 命令问题 - "ng"命令未被识别为内部或外部命令,即使位于 PATH 环境变量中也是如此

aws-lambda - Lambda 函数完成后 Amazon Cloudformation 堆栈挂起

amazon-web-services - 使用子堆栈时,Lambda 代码在 `package` 命令期间不会被压缩