使用 MongoDB 数据库为每个查询打开一个新连接是一个好的做法吗?

Car*_*arl 5 javascript asynchronous mongodb node.js

我正在创建一个 Web 服务器,将用户的数据存储在 MongoDB 数据库中。Web 请求背后的代码使用异步函数将文档插入数据库,但由于这些函数是异步的,这意味着对于每个请求都会与服务器建立一个新连接。

exports.create_user = function(username, password, callback) {
  mongo.connect(url, function(err, db) {
    db.collection('users').insertOne({username: username, password: password}, function(err, result) {
      callback(result)
      db.close()
    })
  })
}
Run Code Online (Sandbox Code Playgroud)

我的印象是,这样做不是最佳实践,但我想不出使用上面使用的模块模型来做到这一点的方法。任何建议或意见将不胜感激。

Mar*_*ies 5

我在自己的研究中偶然发现了这一点:在每个查询上为 mongodb 使用新连接是最佳实践还是使用连接池。事实证明,mongodb 建议对大多数用例使用连接池。

引用文档

连接池是由驱动程序维护的数据库连接的缓存,以便在需要与数据库建立新连接时可以重新使用连接。为了减少应用程序创建的连接池数量,我们建议调用一次 MongoClient.connect 并重用回调返回的数据库变量

我通常使用以下形式在触发查询时建立和重用连接:

// db.js
import { MongoClient } from 'mongodb';

// this will hold our cached database connection, which will itself hold multiple connections in a pool to be used
let connection,
  database;

export {
  connect: (next) => {
    // already established? => return connection
    if (database) return next(undefined, database);

    // establish connection
    MongoClient.connect('http://localhost:27017/admin', (err, db) => {
      if (err) return next(err);

      // save connection
      connection = db;

      // connect to database
      database = db.db('myDatabase');

      // call callback
      next(undefined, database);
    });
  },

  disconnect: (next) => {
    if (!connection) return next();

    // close connection
    connection.close();
    next();
  }
};
Run Code Online (Sandbox Code Playgroud)

触发查询:

import db from './db';

db.connect((err, db) => {
  if (err) return next(err);

  db.collection('myUsers').insertOne({name: 'test'}, (err) => {
    if (err) throw err;

    db.disconnect((err) => {
      if (err) throw err;

      console.log('Everything finished, database connection closed');
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

注意:可以手动确定池连接的最大数量(默认是 5?)。请参阅有关如何通过 mongodb url 设置打开连接数的文档。