我在使用pg-promise和AWS Lambda时遇到了很多问题。我希望了解如何解决这些问题。
该库建议您创建一个Database对象的实例,然后从模块中导出它。应该只创建一个对象的实例。 例如:
const db = pgp({
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT,
database: process.env.DATABASE_NAME,
user: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
poolSize: 0,
poolIdleTimeout: 10,
});
module.exports = db;
我了解这只是一个对象,并没有在此创建连接。只有当您在此db对象上运行任何内容,例如db.query()时,才会延迟创建连接。
由于我们将池大小设置为0,因此只会创建一个连接。这正是我们所需要的,因为在每个lambda函数开始时,我们都需要创建一个连接,然后在lambda完成时关闭连接。
我们面临的问题是:
1. 如何释放连接? AWS Lambda重复使用容器。这意味着它将调用已初始化并重新运行相同功能的相同节点代码,如果在先前运行后不久调用Lambda,则会再次运行相同的函数。 这意味着下一次调用lambda时,db对象将是相同的。在我们的第一个lambda完成后,如果我们调用pgp.end(),文档说连接池将关闭。它还说我们之后不能在同一进程中使用pgp库。但是该库将被使用,因为db对象仍然存在并将在随后的运行中使用。
2. 如何重试获取新连接? AWS Lambda带来的另一个问题是,当您在VPC内运行lambda且您的Postgres实例也在VPC内运行时,需要时间才能解析postgres数据库的DNS。因此,如果尝试连接,可能会出现ENOTFOUND错误。 AWS的建议是重试获取连接。使用pg-promise,我们如何重试获取连接?
我想要实现的方式是:
module.exports.handler = (event, context, callback) => {
let connection;
try {
connection = /*gets connection and retries if it failed the first time*/
// run db queries and transactions.. etc.
callback(null, result);
} finally {
connection.close();
}
}