¿Cómo administro las conexiones MongoDB en una aplicación web Node.js?

Resuelto Freewind asked hace 12 años • 13 respuestas

Estoy usando el controlador nativo de node-mongodb con MongoDB para escribir un sitio web.

Tengo algunas preguntas sobre cómo administrar las conexiones:

  1. ¿Es suficiente usar una sola conexión MongoDB para todas las solicitudes? ¿Hay algún problema de rendimiento? Si no, ¿puedo configurar una conexión global para usar en toda la aplicación?

  2. Si no, ¿es bueno si abro una nueva conexión cuando llega la solicitud y la cierro cuando se maneja la solicitud? ¿Es caro abrir y cerrar una conexión?

  3. ¿Debería utilizar un grupo de conexiones global? He oído que el controlador tiene un grupo de conexiones nativas. ¿Es una buena elección?

  4. Si uso un grupo de conexiones, ¿cuántas conexiones debo usar?

  5. ¿Hay otras cosas que debería notar?

Freewind avatar May 18 '12 23:05 Freewind
Aceptado

El confirmador principal de node-mongodb-native dice :

Abre do MongoClient.connect una vez cuando su aplicación se inicia y reutiliza el objeto db. No es un grupo de conexiones singleton, cada .connect crea un nuevo grupo de conexiones.

Entonces, para responder su pregunta directamente, reutilice el objeto db que resulta deMongoClient.connect() . Esto le brinda agrupación y proporcionará un aumento notable de velocidad en comparación con abrir/cerrar conexiones en cada acción de base de datos.

Max avatar Jan 22 '2013 17:01 Max

Aquí hay un código que administrará sus conexiones MongoDB.

var MongoClient = require('mongodb').MongoClient;
var url = require("../config.json")["MongoDBURL"]

var option = {
  db:{
    numberOfRetries : 5
  },
  server: {
    auto_reconnect: true,
    poolSize : 40,
    socketOptions: {
        connectTimeoutMS: 500
    }
  },
  replSet: {},
  mongos: {}
};

function MongoPool(){}

var p_db;

function initPool(cb){
  MongoClient.connect(url, option, function(err, db) {
    if (err) throw err;

    p_db = db;
    if(cb && typeof(cb) == 'function')
        cb(p_db);
  });
  return MongoPool;
}

MongoPool.initPool = initPool;

function getInstance(cb){
  if(!p_db){
    initPool(cb)
  }
  else{
    if(cb && typeof(cb) == 'function')
      cb(p_db);
  }
}
MongoPool.getInstance = getInstance;

module.exports = MongoPool;

Cuando inicie el servidor, llameinitPool

require("mongo-pool").initPool();

Luego en cualquier otro módulo puedes hacer lo siguiente:

var MongoPool = require("mongo-pool");
MongoPool.getInstance(function (db){
    // Query your MongoDB database.
});

Esto se basa en la documentación de MongoDB . Mira esto.

Yaki Klein avatar Nov 18 '2015 13:11 Yaki Klein

Administre grupos de conexiones mongo en un único módulo autónomo. Este enfoque proporciona dos beneficios. En primer lugar, mantiene su código modular y más fácil de probar. En segundo lugar, no está obligado a mezclar la conexión de su base de datos en su objeto de solicitud, que NO es el lugar para un objeto de conexión de base de datos. (Dada la naturaleza de JavaScript, consideraría muy peligroso mezclar cualquier cosa con un objeto construido mediante código de biblioteca). Entonces con eso solo necesitas considerar un módulo que exporte dos métodos. connect = () => Promisey get = () => dbConnectionObject.

Con dicho módulo, primero puede conectarse a la base de datos.

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

Cuando está en vuelo, su aplicación puede simplemente llamar get()cuando necesita una conexión DB.

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

Si configura su módulo de base de datos de la misma manera que a continuación, no solo tendrá una manera de asegurarse de que su aplicación no se inicie a menos que tenga una conexión de base de datos, sino que también tendrá una forma global de acceder a su grupo de conexiones de base de datos que generará un error. si no tienes conexión.

// 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;
}
Stewart avatar Feb 05 '2017 23:02 Stewart

Si tiene Express.js, puede usar express-mongo-db para almacenar en caché y compartir la conexión MongoDB entre solicitudes sin un grupo (ya que la respuesta aceptada dice que es la forma correcta de compartir la conexión).

De lo contrario, puede consultar su código fuente y utilizarlo en otro marco.

floatdrop avatar Aug 08 '2014 18:08 floatdrop

Debe crear una conexión como servicio y luego reutilizarla cuando sea necesario.

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

mi muestra de 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}`);
  });
});

y úsalo donde quieras con

import dbService from "db.service.js"
const db = dbService.db
0xlkda avatar Oct 26 '2017 20:10 0xlkda