何时何地使用 knex.destroy?

Gro*_*ler 6 javascript node.js knex.js

我对knex.destroy()在我的 Node API 中使用的位置感到困惑。

如果我knex.destroy()打开连接拨打电话后不使用,连接池会随着时间的推移而填满,导致错误:

未处理的拒绝 TimeoutError:Knex:获取连接超时。游泳池可能已经满了。您是否错过了 .transacting(trx) 电话?

如果我关闭连接,这对我来说很有意义,当我完成它时,

router.get('/users', function(req, res, next) {
    var select = knex.select('*').from('users');
    select.then((result) => {
        res.send(result);
    }).catch((error) => {
        res.send(error);
    }).finally(function() {
        knex.destroy(); // close it when I'm done
    });
});
Run Code Online (Sandbox Code Playgroud)

为单独的 API 调用关闭连接:

未处理的拒绝错误:无法在 Client_PG.acquireConnection 处获取连接 (/var/app/current/node_modules/knex/lib/client.js:331:40)

那么,我实际上何时何地破坏了连接?同样,此 Node 应用程序仅用作 API。每个 API 调用都应该打开,然后关闭连接,但knex似乎不喜欢这样。


需要 knex 的路由器文件:(我对每个路由器文件都这样做)

const knexService = require('../knexService');
const bookshelf = knexService.bookshelf;
const knex = knexService.knex;
let User = require('../models/User');

module.exports = function(app, router) {
   router.get('/users', function(req, res, next) {
       var select = knex.select('*').from('users');
       select.then((result) => {
           res.send(result);
       }).catch((error) => {
           res.send(error);
       }).finally(function() {
           knex.destroy(); // close it when I'm done
       });
   });
   ...
Run Code Online (Sandbox Code Playgroud)

用户模型文件

const knexService = require('../knexService');
const bookshelf = knexService.bookshelf;
var BaseModel = require('./BaseModel');
var addressModel = require('./Address').Address;

var User = BaseModel.extend({
    tableName: 'users',
    hasTimestamps: true,
    addresses: function() {
        return this.hasMany(addressModel);
    }
});
Run Code Online (Sandbox Code Playgroud)

KnexService.js

const knexfile = require('./knexfile');
const knex = require('knex')(knexfile.production);
const bookshelf = require('bookshelf')(knex);

module.exports.knex = knex;
module.exports.bookshelf = bookshelf;
Run Code Online (Sandbox Code Playgroud)

KnexFile.js

module.exports = {

    development: {
        client: 'pg',
        version: '7.2',
        connection: {
            ...
Run Code Online (Sandbox Code Playgroud)

Mik*_*stö 6

knex.destroy() 当您想要 knex 丢弃池中的所有连接并停止所有计时器等时应调用,以便应用程序可以正常结束。

所以基本上应该只在应用程序退出时调用,除非您正在做一些更复杂的事情,例如连接到具有多个 knex 实例的多个数据库。

如果您的连接用完并且池已满,则意味着您的代码存在问题。可能的原因可能是:

  • 同时进行太多持久查询
  • 创建事务并且从不提交/回滚,因此这些连接永远不会返回到池中
  • knex/书架/一些中间件中的错误

您应该尝试查明应用程序的哪些部分导致池填满,删除所有额外代码(如bookshelf相关内容)并找到可用于复制问题的最小设置(同时删除所有事务以开始)。

您真的在使用 postgresql 7.2 还是在连接一些自定义的 postgresql 兼容数据库?这可能会导致一些问题,但我认为这些问题不会以这种方式暴露出来,而是通过断开连接留在池中。