Knex.js / SQL : Knex / SQL 连接池

Knex.js / SQL : Knex / SQL Connection Pools

我有一个关于 SQL 连接池的问题。我的团队在我们的一个节点应用程序中使用 knex.js 库来进行数据库查询。 应用程序不时需要切换数据库。所以我的团队创建了一个初始化函数,该函数 returns 一个 knex object 配置到正确的数据库。然后 object 用于执行所述查询。对我来说,这似乎是多余的,并且会导致性能不佳,因为我们每次需要执行查询时都会启动一个 knex object,而不是重复使用单个 knex object。如果 knex 在您使用哪个数据库时已经这样做了,我可以忽略这一点(如果有人也可以阐明这个问题,那将是太棒了!)。此外,(这引出了我上面标题的问题)连接池属性被重新定义。那么这是否意味着我们每次都在创建新的池,或者 SQL(在本例中为 SQL Sever)是否重用您已经定义的连接池?这个问题可能不是特定于 Knex 的,比如如果我使用像 knex 这样的 C# 库,并以类似的方式调用该库,SQL 服务器会知道不要创建更多连接池吗?

示例代码:

/** db.js
 * @param {any} database 
 * @returns db: Knex
 */
module.exports = ( database ) => {
  var knex = require('knex')({
    client: 'mssql',
    connection: {
        database: database,
        server:  '127.0.0.1',
        user: 'your_database_user',
        password: 'your_database_password'
    },
    pool: {
        min: 0,
        max: 10,
        idleTimeoutMillis: 5000,
        softIdleTimeoutMillis: 2000,
        evictionRunIntervalMillis: 500
    }
  });
  return knex; 
}; 


Index.js

var db = require('./db.js'); 
/**
 * @returns users:Array
 */
const getUsers = async() => {
    const users = await db('master')
            .select()
            .from('users_table')
            .orderBy('user_id'); 
    return users; 
}

简短回答: 节点 require() 语句的 'singleton' 性质阻止了多次出现的 knex 的重新初始化。因此,只要您不丢弃 db. 变量引用,最初创建的池将在您的过程期间继续使用,而不是重新创建。

更多讨论...

... my team created an initialization function that returns a knex object configured to the correct database. Then that object is used to do said query. To me this seems redundant and can cause bad performance, because we initiate a knex object every time need to do a query instead of reusing a single knex object. Which i could ignore if knex already does this when you switch databases...

    var db = require('./db.js');

node.js require 语句创建了一个单例对象。 (您可能已经知道)这意味着您的程序第一次使用 require 语句调用模块时,模块及其数据将被初始化,但连续相同的 require 调用将重用相同的模块引用,不会重新初始化模块。

... the connection pool properties are redefined. So does that mean we are creating new pools every time, or does the SQL ( SQL Sever in this case) reuse the connection pool you already defined ?

所以既然require()ed模块没有重新初始化,那么原来创建的pool就不会是re-created。除非你丢弃 db 变量引用(下面详细讨论)。

The question might not be Knex specific, like if i used a library like knex for C#, and call that library a similar way, would SQL Server know not to make more connection pools?

一般来说,您需要构建或获取连接一些代码,以便在您的进程的整个生命周期中正确管理连接池。 Knex 和大多数其他数据库包装器为我们做这件事。 (在幕后,Knex 使用 this library before v0.18.3 and this one on/after。)

正确初始化然后在应用程序进程的整个生命周期中使用单独初始化的池代码可以实现这一点。丢弃池并在您的进程中重新创建它会破坏池的目的。通常将池设置为进程初始化的一部分。

此外,这可能只是您问题中的一个错误陈述,但是您的 Node.js 模块正在创建连接池,而不是 SQL 服务器。

... The application from time to time needs to switch databases. my team created an initialization function that returns a knex object configured to the correct database.

根据该声明,我希望看到如下代码:

var db = require('./db.js');
var dbOther = require('./dbOther.js');

... 分别建立不同的数据库连接。如果您改为使用:

var db = require('./db.js');
// ... do other stuff here in the same module ...
var db = require('./dbOther.js');

...那么您可能会丢弃对第一个数据库的原始引用,在这种情况下,是的,您在切换连接时会丢弃数据库连接和连接池。

或者,您可以执行以下操作:

// initialize the 2 connection pools
const dbFirst = require('./db.js');
const dbOther = require('./dbOther.js');

// set the active connection
var db = dbFirst;
// change the active connection
db = dbOther;