我有一个类似如下的项目。
数据库客户端
const dbClient = require('knex')({
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'user',
password: 'password',
database: 'staging',
port: '5431'
}
})
module.exports = dbClient
libs.js
const knex = require('./dbClient.js')
async function doThis(email) {
const last = await knex('users').where({email}).first('last_name').then(res => res.last_name)
// knex.destroy()
return last
}
async function doThat(email) {
const first = await knex('users').where({email}).first('first_name').then(res => res.first_name)
// knex.destroy()
return first
}
module.exports = {
doThat,
doThis
}
test01.js
const {doThis, doThat} = require('./libs.js');
(async () => {
try {
const res1 = await doThis('user53@gmail.com')
console.log(res1)
const res2 = await doThat('user53@gmail.com')
console.log(res2)
} catch (err) {
console.log(err)
}
})()
当 knex.destroy()
从 libs.js
中移除时,如上所示。 node test01
可以输出res1
和res2
。但问题是连接无限期挂起并且 CMD 永远不会返回。
但如果我从 libs.js
中取消注释 knex.destroy()
,那么 doThis
将执行,CMD 将挂起在 doThat
因为不再有连接已在 doThis
中关闭。
我的问题是:
knex.destroy()
的最佳位置是什么?或者还有其他方法吗?
感谢您的宝贵时间!
最佳答案
Knex destroy()似乎是一次性手术。销毁连接后,下一个操作可能需要一个全新的连接池。
导出的数据库客户端模块is cached进入 Node 模块缓存,并且不会在您每次需要时都创建新的连接池。
这是预期用途,池应该在应用程序退出或所有测试完成时销毁。如果你有理由为每个操作创建/销毁连接(比如在无服务器环境中),你不应该重用被销毁的客户端,而是每次都创建一个新实例。
否则,它会破坏连接池的目的。
更新关于 lambda/无服务器环境:
从技术上讲,函数及其资源将在 lambda 函数运行后释放,这包括它可能已打开的任何连接。这对于真正的无状态函数是必需的。因此,建议在功能完成后关闭连接。但是,大量打开/关闭大量连接的函数最终可能会使数据库服务器耗尽连接(参见 this discussion 例如)。一种解决方案可能是使用像 PgBouncer 这样的中间池或 PgPool协商数据库服务器和 Lambda 函数之间的连接。
另一种方式是平台提供商 (AWS) 为 lambda 环境添加特殊的池化功能,让它们共享长期存在的资源。
关于node.js - 在哪里破坏knex连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54999115/