Lambda INSERT INTO MySql 函数正在添加到数据库但仍然超时
Lambda INSERT INTO MySql function is adding to DB but still timing out
我有一个 Lambda POST 函数,它接受 http 请求 JSON 主体数据并将其添加到连接的 MySql 数据库。
代码如下:
var mysql = require("mysql");
var config = require("./config.json");
var pool = mysql.createPool({
host: config.dbhost,
user: config.dbuser,
password: config.dbpassword,
database: config.dbname,
port: 3306,
ssl: true,
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyjsonLoop = false;
pool.getConnection(function (err, connection) {
const col1 = event.col1;
const col2 = event.col2;
const col3 = event.col3;
// Use the connection
connection.query(
"INSERT INTO table (col1, col2, col3) VALUES(?, ?, ?)",
[col1, col2, col3],
function (error, results, fields) {
// And done with the connection.
connection.release();
var response = {
statusCode: 200,
body: JSON.stringify("Account added successfully!"),
};
// Handle error after the release.
if (error) callback(error);
else callback(null, response.body);
}
);
});
};
我有一个非常相似的 lambda 函数,它从 JSON 更新数据库中的记录,并且运行完美。
测试代码时,记录已成功添加到数据库中。但是,无论我将超时限制设置为多长时间,lambda 函数都会超时。
lambda return出现此错误:
{ "errorMessage": "2021-10-14T10:00:25.159Z 62f12d68-c648-4f0f-9e86-3cd23f0f90c6 Task timed out after 5.01 seconds" }
日志的最后两行是:
Thu Oct 14 10:00:25 UTC 2021 : Successfully completed execution
Thu Oct 14 10:00:25 UTC 2021 : Method completed with status: 200
我已经将代码作为本地文件进行了测试 运行 它使用:node local.js
并且它运行迅速且没有错误。
不确定我错过了什么。也许 INSERT INTO
查询的 return 类型与 UPDATE
不同?
如有任何帮助,我们将不胜感激。谢谢
问题的评论中已经给出了答案,但我想在这里更深入一点,因为在 lambda 函数中使用连接池(大部分)没有用,甚至可能有害.
为什么没用
连接池旨在处理应用程序中与数据库的多个并行连接,在这些应用程序中您可能希望同时处理多个不同的操作(例如,同时处理多个请求的 express API ).然而,AWS Lambda 被设计为只能同时处理单个请求,并且为每个并行执行提供不同的执行环境。这意味着您将从您的数据库请求更多您实际需要的连接。
为什么会坏
您无法控制 lambda 执行环境的终止方式。这也意味着您无法确保您的连接池中的连接会正常关闭,也无法确保数据库服务器会为您关闭它们。如果您随后在 lambda 执行中获得大量增加(通过增加流量或通过在 lambda 中创建循环 - 这很容易完成),您可以很快吃掉数据库可用的所有可用连接,这可能会影响数据库的所有其他客户也是如此。这通常以与经理的一次非常不舒服的谈话结束(去过那里,做过)。
那怎么办呢?
好吧,实际上很简单,创建一个连接,使用它并再次关闭它。下面是这样一个处理函数的示例(使用 postgres 数据库,但应该很容易适应 MySQL):
const pgp = require('pg-promise')();
const getDBConfiguration = require('./db-config');
let dbOptions; // dbOptions are retrieved from SSM param store, we can cache those
const handler = async (event) => {
dbOptions = dbOptions || { ...(await getDBConfiguration()), max: 1 }; // restrict number of connections in pool to one
const client = pgp(dbOptions);
try {
await client.any(/*Execute some query*/);
} finally {
await client.$pool.end();
}
};
我有一个 Lambda POST 函数,它接受 http 请求 JSON 主体数据并将其添加到连接的 MySql 数据库。
代码如下:
var mysql = require("mysql");
var config = require("./config.json");
var pool = mysql.createPool({
host: config.dbhost,
user: config.dbuser,
password: config.dbpassword,
database: config.dbname,
port: 3306,
ssl: true,
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyjsonLoop = false;
pool.getConnection(function (err, connection) {
const col1 = event.col1;
const col2 = event.col2;
const col3 = event.col3;
// Use the connection
connection.query(
"INSERT INTO table (col1, col2, col3) VALUES(?, ?, ?)",
[col1, col2, col3],
function (error, results, fields) {
// And done with the connection.
connection.release();
var response = {
statusCode: 200,
body: JSON.stringify("Account added successfully!"),
};
// Handle error after the release.
if (error) callback(error);
else callback(null, response.body);
}
);
});
};
我有一个非常相似的 lambda 函数,它从 JSON 更新数据库中的记录,并且运行完美。
测试代码时,记录已成功添加到数据库中。但是,无论我将超时限制设置为多长时间,lambda 函数都会超时。
lambda return出现此错误:
{ "errorMessage": "2021-10-14T10:00:25.159Z 62f12d68-c648-4f0f-9e86-3cd23f0f90c6 Task timed out after 5.01 seconds" }
日志的最后两行是:
Thu Oct 14 10:00:25 UTC 2021 : Successfully completed execution
Thu Oct 14 10:00:25 UTC 2021 : Method completed with status: 200
我已经将代码作为本地文件进行了测试 运行 它使用:node local.js
并且它运行迅速且没有错误。
不确定我错过了什么。也许 INSERT INTO
查询的 return 类型与 UPDATE
不同?
如有任何帮助,我们将不胜感激。谢谢
问题的评论中已经给出了答案,但我想在这里更深入一点,因为在 lambda 函数中使用连接池(大部分)没有用,甚至可能有害.
为什么没用
连接池旨在处理应用程序中与数据库的多个并行连接,在这些应用程序中您可能希望同时处理多个不同的操作(例如,同时处理多个请求的 express API ).然而,AWS Lambda 被设计为只能同时处理单个请求,并且为每个并行执行提供不同的执行环境。这意味着您将从您的数据库请求更多您实际需要的连接。
为什么会坏
您无法控制 lambda 执行环境的终止方式。这也意味着您无法确保您的连接池中的连接会正常关闭,也无法确保数据库服务器会为您关闭它们。如果您随后在 lambda 执行中获得大量增加(通过增加流量或通过在 lambda 中创建循环 - 这很容易完成),您可以很快吃掉数据库可用的所有可用连接,这可能会影响数据库的所有其他客户也是如此。这通常以与经理的一次非常不舒服的谈话结束(去过那里,做过)。
那怎么办呢?
好吧,实际上很简单,创建一个连接,使用它并再次关闭它。下面是这样一个处理函数的示例(使用 postgres 数据库,但应该很容易适应 MySQL):
const pgp = require('pg-promise')();
const getDBConfiguration = require('./db-config');
let dbOptions; // dbOptions are retrieved from SSM param store, we can cache those
const handler = async (event) => {
dbOptions = dbOptions || { ...(await getDBConfiguration()), max: 1 }; // restrict number of connections in pool to one
const client = pgp(dbOptions);
try {
await client.any(/*Execute some query*/);
} finally {
await client.$pool.end();
}
};