362 Stimmen

Wie verwalte ich MongoDB-Verbindungen in einer Node.js-Webanwendung?

Ich benutze die node-mongodb-native Treiber mit MongoDB, um eine Website zu schreiben.

Ich habe einige Fragen zur Verwaltung von Verbindungen:

  1. Reicht es aus, nur eine MongoDB-Verbindung für alle Anfragen zu verwenden? Gibt es irgendwelche Leistungsprobleme? Wenn nicht, kann ich eine globale Verbindung einrichten, die für die gesamte Anwendung verwendet wird?

  2. Wenn nicht, ist es gut, wenn ich eine neue Verbindung öffne, wenn die Anfrage ankommt, und sie schließe, wenn die Anfrage bearbeitet wurde? Ist es teuer, eine Verbindung zu öffnen und zu schließen?

  3. Sollte ich einen globalen Verbindungspool verwenden? Ich habe gehört, dass der Treiber einen nativen Verbindungspool hat. Ist das eine gute Wahl?

  4. Wenn ich einen Verbindungspool verwende, wie viele Verbindungen sollten verwendet werden?

  5. Gibt es noch andere Dinge, die ich beachten sollte?

539voto

Max Punkte 11038

Der Hauptverantwortliche für node-mongodb-native sagt :

Sie öffnen MongoClient.connect einmal beim Hochfahren Ihrer Anwendung und verwenden das db-Objekt wieder. Es handelt sich nicht um einen Singleton-Verbindungspool, den jedes .connect erstellt einen neuen Verbindungspool.

Um Ihre Frage also direkt zu beantworten, das db-Objekt wiederverwenden, das sich aus MongoClient.connect() . Dadurch erhalten Sie ein Pooling, das eine spürbare Geschwindigkeitssteigerung gegenüber dem Öffnen/Schließen von Verbindungen bei jeder DB-Aktion bewirkt.

65voto

Konstantin Tarkus Punkte 36184

Öffnen Sie eine neue Verbindung, wenn die Node.js-Anwendung startet, und verwenden Sie die bestehende db Verbindungsobjekt:

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

Source : Öffnen von Datenbank-Verbindungen in einer Node.js/Express App

27voto

Yaki Klein Punkte 3152

Hier finden Sie einige Codes, die Ihre MongoDB-Verbindungen verwalten werden.

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;

Wenn Sie den Server starten, rufen Sie initPool

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

In jedem anderen Modul können Sie dann Folgendes tun:

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

Dies beruht auf MongoDB-Dokumentation . Schauen Sie es sich an.

23voto

Stewart Punkte 2743

Verwalten Sie Mongo-Verbindungspools in einem einzigen, eigenständigen Modul. Dieser Ansatz bietet zwei Vorteile. Erstens bleibt Ihr Code modular und lässt sich leichter testen. Zweitens ist man nicht gezwungen, die Datenbankverbindung in das Request-Objekt zu mischen, was NICHT der richtige Ort für ein Datenbankverbindungsobjekt ist. (In Anbetracht der Natur von JavaScript würde ich es für sehr gefährlich halten, irgendetwas in ein Objekt zu mischen, das durch Bibliothekscode konstruiert wurde). Damit brauchen Sie nur ein Modul zu betrachten, das zwei Methoden exportiert. connect = () => Promise y get = () => dbConnectionObject .

Mit einem solchen Modul können Sie zunächst eine Verbindung zur Datenbank herstellen

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

Während des Fluges kann Ihre Anwendung einfach Folgendes aufrufen get() wenn es eine DB-Verbindung benötigt.

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

Wenn Sie Ihr DB-Modul wie folgt einrichten, können Sie nicht nur sicherstellen, dass Ihre Anwendung nicht startet, wenn Sie keine Datenbankverbindung haben, sondern Sie haben auch eine globale Möglichkeit, auf Ihren Datenbankverbindungspool zuzugreifen, die einen Fehler auslöst, wenn Sie keine Verbindung haben.

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

12voto

floatdrop Punkte 615

Wenn Sie Express.js haben, können Sie express-mongo-db für die Zwischenspeicherung und gemeinsame Nutzung der MongoDB-Verbindung zwischen Anfragen ohne Pool (da die akzeptierte Antwort besagt, dass dies der richtige Weg zur gemeinsamen Nutzung der Verbindung ist).

Wenn nicht, können Sie sich den Quellcode ansehen und ihn in einem anderen Framework verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X