मैं Node.js वेब एप्लिकेशन में MongoDB कनेक्शन कैसे प्रबंधित करूं?




database-connection connection-pooling (7)

Node.js एप्लिकेशन प्रारंभ होने पर एक नया कनेक्शन खोलें, और मौजूदा db कनेक्शन ऑब्जेक्ट का पुन: उपयोग करें:

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

स्रोत: किसी नोड.जेएस / एक्सप्रेस ऐप में डेटाबेस कनेक्शन कैसे खोलें

मैं एक वेबसाइट लिखने के लिए मोंगोडीबी के साथ node-mongodb-native चालक का उपयोग कर रहा हूं।

कनेक्शन के प्रबंधन के बारे में मेरे कुछ प्रश्न हैं:

  1. क्या यह सभी अनुरोधों के लिए केवल एक मोंगोडीबी कनेक्शन का उपयोग कर पर्याप्त है? क्या कोई प्रदर्शन समस्या है? यदि नहीं, तो क्या मैं पूरे एप्लिकेशन में उपयोग करने के लिए वैश्विक कनेक्शन स्थापित कर सकता हूं?

  2. यदि नहीं, तो क्या यह अच्छा है अगर अनुरोध आने पर नया कनेक्शन खुलता है, और अनुरोध को संभालने पर इसे बंद कर देता है? क्या कनेक्शन खोलना और बंद करना महंगा है?

  3. क्या मुझे वैश्विक कनेक्शन पूल का उपयोग करना चाहिए? मैंने सुना है कि चालक का मूल कनेक्शन पूल है। क्या यह एक अच्छा विकल्प है?

  4. यदि मैं कनेक्शन पूल का उपयोग करता हूं, तो कितने कनेक्शन का उपयोग किया जाना चाहिए?

  5. क्या मुझे अन्य बातों पर ध्यान देना चाहिए?


आपको सेवा के रूप में कनेक्शन बनाना चाहिए और आवश्यकता होने पर इसका पुन: उपयोग करना चाहिए।

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

मेरा 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}`);
  });
});

और जहां भी आप चाहते हैं इसका इस्तेमाल करें

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

कनेक्शन पूलिंग को लागू करने का सबसे अच्छा तरीका यह है कि आपको एक ग्लोबल एरे वैरिएबल बनाना चाहिए जो मोंगो क्लाइंट द्वारा लौटाए गए कनेक्शन ऑब्जेक्ट के साथ डीबी नाम धारण करे और फिर जब भी आपको डेटाबेस से संपर्क करने की आवश्यकता हो तो उस कनेक्शन का पुन: उपयोग करें।

  1. अपने server.js में var global.dbconnections = [] को परिभाषित करें;

  2. सेवा नामकरण कनेक्शन सेवा.जेएस बनाएँ। इसमें 2 विधियां मिलेंगी कनेक्शन और निर्माण कनेक्शन। तो जब उपयोगकर्ता getConnection () को कॉल करेगा, तो उसे ग्लोबल कनेक्शन वैरिएबल में विस्तार मिलेगा और यदि कनेक्शन पहले से मौजूद है तो रिटर्न कनेक्शन विवरण होगा, तो यह createConnection () को कॉल करेगा और कनेक्शन विवरण वापस करेगा।

  3. Db_name का उपयोग करके इस सेवा को कॉल करें और यह कनेक्शन ऑब्जेक्ट वापस कर देगा यदि उसके पास पहले से ही है तो यह नया कनेक्शन बनाएगा और इसे आपके पास वापस कर देगा।

आशा करता हूँ की ये काम करेगा :)

कनेक्शनService.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;
} 

मैं अपने ऐप में रेडिस कनेक्शन के साथ जेनेरिक पूल का उपयोग कर रहा हूं - मैं अत्यधिक अनुशंसा करता हूं। इसकी सामान्य और मुझे निश्चित रूप से पता है कि यह mysql के साथ काम करता है इसलिए मुझे नहीं लगता कि आपको इसके साथ कोई समस्या होगी और मोंगो

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


यदि आपके पास Express.js है, तो आप पूल के बिना अनुरोधों के बीच मोंगोडीबी कनेक्शन को कैशिंग और साझा करने के लिए github.com/floatdrop/express-mongo-db उपयोग कर सकते हैं (क्योंकि स्वीकृत उत्तर कहता है कि यह कनेक्शन साझा करने का सही तरीका है)।

यदि नहीं - तो आप इसके स्रोत कोड को देख सकते हैं और इसे किसी अन्य ढांचे में उपयोग कर सकते हैं।


यहां कुछ कोड है जो आपके मोंगोडीबी कनेक्शन का प्रबंधन करेगा।

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;

जब आप सर्वर प्रारंभ करते हैं, तो initPool कॉल करें

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

फिर किसी भी अन्य मॉड्यूल में आप निम्न कार्य कर सकते हैं:

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

यह मोंगोडीबी दस्तावेज पर आधारित है। इस पर एक नज़र मारो।


नोड-मोंगोड-मूल के लिए प्राथमिक कमिश्नर कहते हैं :

जब आप अपना ऐप बूट करते हैं और डीबी ऑब्जेक्ट का पुन: उपयोग करते हैं तो आप एक बार MongoClient.connect खोलते हैं। यह एक सिंगलटन कनेक्शन पूल नहीं है। कनेक्ट एक नया कनेक्शन पूल बनाता है।

तो, सीधे अपने प्रश्न का उत्तर देने के लिए, डीबी ऑब्जेक्ट का पुन: उपयोग करें जो मोंगो क्लाइंट.कनेक्ट () से मिलता है। यह आपको पूलिंग देता है, और प्रत्येक डीबी कार्रवाई पर खोलने / समापन कनेक्शन की तुलना में एक उल्लेखनीय गति वृद्धि प्रदान करेगा।





connection-pooling