我使用node-mongodb-native驱动与MongoDB写一个网站。

我有一些关于如何管理连接的问题:

Is it enough using only one MongoDB connection for all requests? Are there any performance issues? If not, can I setup a global connection to use in the whole application? If not, is it good if I open a new connection when request arrives, and close it when handled the request? Is it expensive to open and close a connection? Should I use a global connection pool? I hear the driver has a native connection pool. Is it a good choice? If I use a connection pool, how many connections should be used? Are there other things I should notice?


当前回答

node-mongodb-native的主提交者说:

打开MongoClient。连接一次,当你的应用程序启动和重用 db对象。每个.connect并不是一个单独的连接池 创建一个新的连接池。

因此,为了直接回答您的问题,重用MongoClient.connect()生成的db对象。这为您提供了池化,与在每个db操作上打开/关闭连接相比,将提供显著的速度提高。

其他回答

我已经在我的项目中实现了下面的代码,在我的代码中实现连接池,这样它将在我的项目中创建一个最小的连接,并重用可用的连接

/* Mongo.js*/

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/yourdatabasename"; 
var assert = require('assert');

var connection=[];
// Create the database connection
establishConnection = function(callback){

                MongoClient.connect(url, { poolSize: 10 },function(err, db) {
                    assert.equal(null, err);

                        connection = db
                        if(typeof callback === 'function' && callback())
                            callback(connection)

                    }

                )



}

function getconnection(){
    return connection
}

module.exports = {

    establishConnection:establishConnection,
    getconnection:getconnection
}

/*app.js*/
// establish one connection with all other routes will use.
var db = require('./routes/mongo')

db.establishConnection();

//you can also call with callback if you wanna create any collection at starting
/*
db.establishConnection(function(conn){
  conn.createCollection("collectionName", function(err, res) {
    if (err) throw err;
    console.log("Collection created!");
  });
};
*/

// anyother route.js

var db = require('./mongo')

router.get('/', function(req, res, next) {
    var connection = db.getconnection()
    res.send("Hello");

});

node-mongodb-native的主提交者说:

打开MongoClient。连接一次,当你的应用程序启动和重用 db对象。每个.connect并不是一个单独的连接池 创建一个新的连接池。

因此,为了直接回答您的问题,重用MongoClient.connect()生成的db对象。这为您提供了池化,与在每个db操作上打开/关闭连接相比,将提供显著的速度提高。

我一直在我的应用程序中使用redis连接的通用池-我强烈推荐它。它是通用的,我肯定知道它适用于mysql,所以我不认为你会有任何问题与它和mongo

https://github.com/coopernurse/node-pool

使用下面的方法,您可以轻松地管理尽可能多的连接

var mongoose = require('mongoose');


//Set up default mongoose connection
const bankDB = ()=>{
    return  mongoose.createConnection('mongodb+srv://<username>:<passwprd>@mydemo.jk4nr.mongodb.net/<database>?retryWrites=true&w=majority',options);
    
}

bankDB().then(()=>console.log('Connected to mongoDB-Atlas bankApp...'))
       .catch((err)=>console.error('Could not connected to mongoDB',err));
       
//Set up second mongoose connection
const myDB = ()=>{
    return  mongoose.createConnection('mongodb+srv://<username>:<password>@mydemo.jk4nr.mongodb.net/<database>?retryWrites=true&w=majority',options);
   
}
myDB().then(()=>console.log('Connected to mongoDB-Atlas connection 2...'))
       .catch((err)=>console.error('Could not connected to mongoDB',err));

module.exports = { bankDB(), myDB() };

Manage mongo connection pools in a single self contained module. This approach provides two benefits. Firstly it keeps your code modular and easier to test. Secondly your not forced to mix your database connection up in your request object which is NOT the place for a database connection object. (Given the nature of JavaScript I would consider it highly dangerous to mix in anything to an object constructed by library code). So with that you only need to Consider a module that exports two methods. connect = () => Promise and get = () => dbConnectionObject.

使用这样的模块,您可以首先连接到数据库

// runs in boot.js or what ever file your application starts with
const db = require('./myAwesomeDbModule');
db.connect()
    .then(() => console.log('database connected'))
    .then(() => bootMyApplication())
    .catch((e) => {
        console.error(e);
        // Always hard exit on a database connection error
        process.exit(1);
    });

当你的应用程序运行时,当它需要一个DB连接时,你可以简单地调用get()。

const db = require('./myAwesomeDbModule');
db.get().find(...)... // I have excluded code here to keep the example  simple

如果你像下面这样设置你的db模块,你不仅可以确保你的应用程序不会启动,除非你有一个数据库连接,你也有一个全局的方式来访问你的数据库连接池,如果你没有连接,它会出错。

// myAwesomeDbModule.js
let connection = null;

module.exports.connect = () => new Promise((resolve, reject) => {
    MongoClient.connect(url, option, function(err, db) {
        if (err) { reject(err); return; };
        resolve(db);
        connection = db;
    });
});

module.exports.get = () => {
    if(!connection) {
        throw new Error('Call connect first!');
    }

    return connection;
}