node.js - 在哪里破坏 knex 连接
问题描述
我有一个类似于以下的项目。
dbClient.js
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 永远不会返回。
但是,如果我取消注释knex.destroy()
,libs.js
则将doThis
执行,CMD 将挂起,doThat
因为不再有已关闭的连接doThis
。
我的问题是:
什么是最好的位置knex.destroy()
?或者还有其他方法可以做到吗?
谢谢你的时间!
解决方案
Knex destroy()似乎是一次性操作。销毁连接后,下一次操作可能需要一个全新的连接池。
您导出的 db 客户端模块缓存到节点模块缓存中,并且不会在您每次需要时创建新的连接池。
这是预期用途,当应用程序退出或所有测试完成时,池应该被销毁。如果您有理由为每个操作创建/销毁连接(例如在无服务器环境中),则不应重用已销毁的客户端,而应每次都创建一个新实例。
否则,它就达不到连接池的目的。
关于 lambda/server-less 环境的更新:
从技术上讲,函数及其资源将在 lambda 函数运行后释放,这包括它可能打开的任何连接。这对于真正的无状态函数是必要的。因此建议在功能完成时关闭连接。但是,许多打开/关闭大量连接的函数最终可能会导致数据库服务器用尽连接(例如,请参阅此讨论)。一种解决方案可能是使用像 PgBouncer 或 PgPool 这样的中间池来协商数据库服务器和 Lambda 函数之间的连接。
另一种方式是让平台提供商 (AWS) 为 lambda 环境添加特殊的池化功能,并让它们共享长期存在的资源。
推荐阅读
- ios - SwiftUI 基础动画
- ios - Swift NumberFormatter 只为千
- node.js - 如何要求一个想要成为模块的节点包,没有类型:模块
- python - 标准化numpy数组/出现矩阵“跨对角线”
- audio - 如何将音频波形制作成 128*100x 频谱图
- javascript - 需要在我的成功函数中正确映射数据
- cloudkit - UICloudSharingController 在 iOS 15.x 中不显示具有现有共享的“添加人员”,但在 iOS 14.x 中显示
- java - Java中的两级深拷贝
- nginx - 多语言 Angular 应用程序的浏览器缓存 nginx 配置
- typescript - 基于条件参数的函数的条件返回