true Come posso gestire le connessioni MongoDB in un'applicazione web Node.js?




use mongoclient true (8)

Sto usando il driver node-mongodb-native con MongoDB per scrivere un sito web.

Ho alcune domande su come gestire le connessioni:

  1. È sufficiente utilizzare una sola connessione MongoDB per tutte le richieste? Ci sono problemi di prestazioni? In caso contrario, posso impostare una connessione globale da utilizzare nell'intera applicazione?

  2. In caso contrario, è utile aprire una nuova connessione quando arriva la richiesta e chiuderla quando viene gestita la richiesta? È costoso aprire e chiudere una connessione?

  3. Dovrei usare un pool di connessione globale? Ho sentito che il driver ha un pool di connessione nativo. è una buona scelta?

  4. Se utilizzo un pool di connessioni, quante connessioni dovrebbero essere utilizzate?

  5. Ci sono altre cose che dovrei notare?


Ho usato il generico pool con connessioni redis nella mia app - lo consiglio vivamente. È generico e sicuramente so che funziona con mysql, quindi non penso che avrai problemi con esso e mongo

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


http://mongoosejs.com/docs/api.html

Controlla la fonte di Mongoose. Aprono una connessione e la collegano a un oggetto Modello, quindi quando è richiesto l'oggetto modello, viene effettuata una connessione al DB. Il driver si occupa del pooling delle connessioni.


Migliore approccio per implementare il pool di connessioni è necessario creare una variabile di array globale che contenga il nome di db con l'oggetto di connessione restituito da MongoClient e quindi riutilizzare tale connessione ogni volta che è necessario contattare Database.

  1. Nel tuo Server.js definisci var global.dbconnections = [];

  2. Creare un servizio di denominazione connectionService.js. Avrà 2 metodi getConnection e createConnection. Pertanto, quando l'utente chiamerà getConnection (), troverà i dettagli nella variabile di connessione globale e restituirà i dettagli della connessione se già esiste altrimenti chiamerà createConnection () e restituirà i dettagli della connessione.

  3. Chiama questo servizio usando db_name e restituirà l'oggetto di connessione se già lo ha già, creerà una nuova connessione e te la restituirà.

Spero che sia d'aiuto :)

Ecco il codice connectionService.js:

var mongo = require('mongoskin');
var mongodb = require('mongodb');
var Q = require('q');
var service = {};
service.getConnection = getConnection ;
module.exports = service;

function getConnection(appDB){
    var deferred = Q.defer();
    var connectionDetails=global.dbconnections.find(item=>item.appDB==appDB)

    if(connectionDetails){deferred.resolve(connectionDetails.connection);
    }else{createConnection(appDB).then(function(connectionDetails){
            deferred.resolve(connectionDetails);})
    }
    return deferred.promise;
}

function createConnection(appDB){
    var deferred = Q.defer();
    mongodb.MongoClient.connect(connectionServer + appDB, (err,database)=> 
    {
        if(err) deferred.reject(err.name + ': ' + err.message);
        global.dbconnections.push({appDB: appDB,  connection: database});
        deferred.resolve(database);
    })
     return deferred.promise;
} 

Se si dispone di Express.js, è possibile utilizzare github.com/floatdrop/express-mongo-db per la memorizzazione nella cache e la condivisione della connessione MongoDB tra richieste senza pool (poiché la risposta accettata indica che è il modo giusto per condividere la connessione).

Altrimenti, puoi guardare il suo codice sorgente e usarlo in un'altra struttura.


È necessario creare una connessione come servizio, quindi riutilizzarla quando necessario.

// db.service.js
import { MongoClient } from "mongodb";
import database from "../config/database";

const dbService = {
  db: undefined,
  connect: callback => {
    MongoClient.connect(database.uri, function(err, data) {
      if (err) {
        MongoClient.close();
        callback(err);
      }
      dbService.db = data;
      console.log("Connected to database");
      callback(null);
    });
  }
};

export default dbService;

il mio esempio App.js

// App Start
dbService.connect(err => {
  if (err) {
    console.log("Error: ", err);
    process.exit(1);
  }

  server.listen(config.port, () => {
    console.log(`Api runnning at ${config.port}`);
  });
});

e usalo ovunque tu voglia

import dbService from "db.service.js"
const db = dbService.db

Aprire una nuova connessione all'avvio dell'applicazione Node.js e riutilizzare l'oggetto di connessione db esistente:

/server.js

import express from 'express';
import Promise from 'bluebird';
import logger from 'winston';
import { MongoClient } from 'mongodb';
import config from './config';
import usersRestApi from './api/users';

const app = express();

app.use('/api/users', usersRestApi);

app.get('/', (req, res) => {
  res.send('Hello World');
});

// Create a MongoDB connection pool and start the application
// after the database connection is ready
MongoClient.connect(config.database.url, { promiseLibrary: Promise }, (err, db) => {
  if (err) {
    logger.warn(`Failed to connect to the database. ${err.stack}`);
  }
  app.locals.db = db;
  app.listen(config.port, () => {
    logger.info(`Node.js app is listening at http://localhost:${config.port}`);
  });
});

/api/users.js

import { Router } from 'express';
import { ObjectID } from 'mongodb';

const router = new Router();

router.get('/:id', async (req, res, next) => {
  try {
    const db = req.app.locals.db;
    const id = new ObjectID(req.params.id);
    const user = await db.collection('user').findOne({ _id: id }, {
      email: 1,
      firstName: 1,
      lastName: 1
    });

    if (user) {
      user.id = req.params.id;
      res.send(user);
    } else {
      res.sendStatus(404);
    }
  } catch (err) {
    next(err);
  }
});

export default router;

Origine: come aprire le connessioni del database in un'app Node.js / Express


Gestisci i pool di connessioni mongo in un unico modulo autonomo. Questo approccio offre due vantaggi. In primo luogo mantiene il codice modulare e più facile da testare. In secondo luogo, non è obbligato a mescolare la connessione del database nell'oggetto di richiesta che NON è il posto per un oggetto di connessione al database. (Data la natura di JavaScript, ritengo molto pericoloso mescolare qualcosa con un oggetto costruito dal codice della libreria). Quindi con quello basta prendere in considerazione un modulo che esporta due metodi. connect = () => Promise and get = () => dbConnectionObject .

Con tale modulo è possibile innanzitutto connettersi al database

// 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);
    });

Quando sei in volo, la tua app può semplicemente chiamare get() quando ha bisogno di una connessione DB.

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

Se si imposta il modulo db nello stesso modo in cui si segue non solo si avrà un modo per assicurarsi che l'applicazione non si avvii a meno che non si disponga di una connessione al database, si avrà anche un modo globale di accedere al pool di connessioni del database che causerà un errore se non hai una connessione.

// 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;
}

Ho implementato il codice seguente nel mio progetto per implementare il pool di connessioni nel mio codice in modo da creare una connessione minima nel mio progetto e riutilizzare la connessione disponibile

/* 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");

});




connection-pooling