使用 MongoDB 数据库为每个查询打开一个新连接是一种好习惯吗?

Posted

技术标签:

【中文标题】使用 MongoDB 数据库为每个查询打开一个新连接是一种好习惯吗?【英文标题】:Is opening a new connection for each query with a MongoDB database good practise? 【发布时间】:2017-09-27 16:18:09 【问题描述】:

我正在创建一个将用户数据存储在 MongoDB 数据库中的 Web 服务器。 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()
    )
  )

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

【问题讨论】:

【参考方案1】:

通过db.close()你可以关闭连接,如果你不关闭你的连接,事件循环将保持连接打开并且你的进程不会退出。如果您正在构建一个不会终止进程的 Web 服务器,则无需关闭连接。 供参考node-mongodb-native

【讨论】:

【参考方案2】:

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

引用自docs:

连接池是由驱动程序维护的数据库连接缓存,以便在需要到数据库的新连接时可以重新使用连接。为了减少您的应用程序创建的连接池的数量,我们建议调用一次 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();
  
;

触发查询:

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');
    );
  );
);

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

【讨论】:

以上是关于使用 MongoDB 数据库为每个查询打开一个新连接是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 2.6:实例/数据库级别的maxTimeMS

在mongodb中聚类地理数据

MongoDB 学习笔记之 分析器和explain

MongoDB高级操作

mongodb 怎么限制文档数量

mongoDB 以微秒为单位获取查询的执行时间