在Lambda中何时释放连接和清理资源。在正常的Node JS应用程序中,我们使用挂钩(hook)
process.on('exit', (code) => {
console.log(`About to exit with code: ${code}`);
});
然而,在 AWS Lambda 上这种方法不起作用,导致 MySQL 连接处于睡眠模式。我们没有足够的资源来维持这样的活跃连接。AWS 的文档中没有指明如何实现这一点。
如何接收 AWS Lambda 容器的停止事件?
在Lambda中何时释放连接和清理资源。在正常的Node JS应用程序中,我们使用挂钩(hook)
process.on('exit', (code) => {
console.log(`About to exit with code: ${code}`);
});
然而,在 AWS Lambda 上这种方法不起作用,导致 MySQL 连接处于睡眠模式。我们没有足够的资源来维持这样的活跃连接。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);
}
});
};
注意:我没有测试过这段代码。我只是提供了一个讨论的例子。
我也看到过像这样的对话,讨论将连接放在主函数体外的可能性:
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 在第一次调用函数后会尝试重复使用现有容器,下一次函数调用将已经打开了一个数据库连接。上面的例子应该在使用之前检查是否存在打开的连接,但你明白了。
当然问题是这样会无限期地保持你的连接处于打开状态。我不喜欢这种方法,但根据你特定的情况,这可能有效。你也可以在这种情况下引入连接池。但无论如何,在这种情况下你没有事件清洁地销毁连接或连接池。托管您的函数的容器进程本身将被终止。因此,您必须依赖于数据库在某个时候从其端口关闭连接。
我可能对其中一些细节理解错误,但我相信在高层次上这就是您要考虑的内容。希望能帮到您!