knex 连接在路由完成后不会直接释放(并且连接对象超出范围)

knex connections aren't directly freed after a route has finished (and connection object goes out of scope)

在我的应用程序中,我仅在路由处理期间创建 knex 连接对象,而不是 "on script loading",因为配置已在别处加载到全局对象中 (Sails)。

因此代码看起来有点像:

const knexBuilder = require('knex');
function db() {
  if (!!sails && !!sails.config && !!sails.config.datastores && !!sails.config.datastores.default) {
    return knexBuilder({
      client: 'pg',
      connection: sails.config.datastores.default,
    })
  } else {
    throw new Error('sails not initialized, can\'t load db');
  }
}
module.exports = {
  getEventDates: async function(req: RequestTy, res: ResponseTy) {
    const sess = req.session;
    try {   
      const dbObject = db();
      const dbPromise = dbObject
        .select(`ed.${EventDate.schema.event.columnName}`, `ed.${EventDate.schema.start_date.columnName}`)
        .from(`public.${EventDate.tableName} as ed`);
      const data = await dbPromise;

      return res.json(data);
    } catch(err) {
      console.log(err);
      return res.status(500).send('problems');
    }
  },
}

现在我注意到数据库的连接数在不断增加。随着时间的推移,缓慢的连接被丢弃,但在我们的应用程序中,这很快会导致一次连接太多的错误。即使只有少数人(每个打开前端页面的用户每隔几秒调用一次上述函数)。

那么我怎样才能强制 knex 表现得很好并自行清理并在对象超出范围时立即删除数据库连接?

每次调用创建新 knex 实例的 db() 函数时,您都在创建新的连接池。这也迫使 knex 在每次请求时创建与数据库的新连接,因为它不能使用来自那些旧的废弃 knex 实例的旧打开连接。

在你的 db() 函数中,你应该首先检查你是否已经创建了一个 knex 实例,如果你已经 return 已经创建了一个。

基本上你不应该在你的应用程序中创建多个 knex 实例,除非你连接多个数据库。