programing

Node.js 웹 응용 프로그램에서 MongoDB 연결을 관리하는 방법은 무엇입니까?

testmans 2023. 3. 16. 21:14
반응형

Node.js 웹 응용 프로그램에서 MongoDB 연결을 관리하는 방법은 무엇입니까?

웹 사이트를 작성하기 위해 MongoDB와 노드-몽고드 네이티브 드라이버를 사용하고 있습니다.

접속 관리 방법에 대해 몇 가지 질문이 있습니다.

  1. 모든 요청에 대해 하나의 MongoDB 연결만 사용하는 것으로 충분합니까?퍼포먼스에 문제가 있습니까?그렇지 않은 경우 전체 응용 프로그램에서 사용하도록 글로벌 연결을 설정할 수 있습니까?

  2. 그렇지 않은 경우 요청이 도착했을 때 연결을 새로 열고 요청 처리 시 연결을 닫는 것이 좋습니까?연결을 열고 닫는 데 비용이 많이 드나요?

  3. 글로벌 연결 풀을 사용해야 합니까?운전기사가 원어민 연결 풀을 가지고 있다고 들었어요.좋은 선택인가요?

  4. 연결 풀을 사용할 경우 몇 개의 연결을 사용해야 합니까?

  5. 또 주의해야 할 게 있나요?

node-mongodb-native에 대한 프라이머리 커밋은 다음과 같습니다.

앱 부팅 시 Do MongoClient.connect를 한 번 열고 db 객체를 재사용합니다.이것은 싱글톤 접속 풀이 아닙니다.각 .connect는 새로운 접속 풀을 만듭니다.

따라서 질문에 직접 답변하려면 에서 생성된 DB 개체를 다시 사용합니다.이를 통해 풀링 기능이 제공되며 각 DB 액션의 연결을 열거나 닫을 때보다 속도가 크게 향상됩니다.

Node되면 새 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.js/Express 앱에서 데이터베이스 연결을 여는 방법

다음은 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;

하면, 「」를 호출해 .initPool

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

다른 모듈에서는 다음 작업을 수행할 수 있습니다.

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

이는 MongoDB 문서를 기반으로 합니다.한번 봐.

몽고 1번지이 방법에는 두 가지 이점이 있습니다.첫째, 코드를 모듈식으로 유지하여 테스트하기 쉽게 합니다.둘째, 데이터베이스 접속 오브젝트가 아닌 요청 오브젝트에 데이터베이스 접속을 강제로 혼재시키지 않습니다.(JavaScript의 특성상 라이브러리 코드로 작성된 오브젝트에 어떤 것이든 혼재시키는 것은 매우 위험하다고 생각합니다.)따라서 두 가지 메서드를 내보내는 모듈을 고려하기만 하면 됩니다. connect = () => Promise ★★★★★★★★★★★★★★★★★」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);
    });

중 은 단순히 할 수 .get()DB를 사용합니다.

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

Express.js가 있는 경우 express-mongo-db를 사용하여 풀 없이 요청 간에 MongoDB 연결을 캐싱 및 공유할 수 있습니다(접속된 답변은 연결을 공유하는 올바른 방법이라고 합니다).

그렇지 않은 경우 - 소스 코드를 보고 다른 프레임워크에서 사용할 수 있습니다.

서비스로 연결을 만든 후 필요할 때 다시 사용해야 합니다.

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

앱에서 redis 접속이 있는 범용 풀을 사용하고 있습니다.강력히 추천합니다.일반적이고 mysql과 연동되는 것은 확실하기 때문에 문제없을 것 같고 mongo도 문제없을 것 같습니다.

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

코드에 접속 풀링을 구현하기 위해 프로젝트에서 다음 코드를 구현했습니다.이것에 의해, 프로젝트에서 최소한의 접속을 확립해, 사용 가능한 접속을 재사용할 수 있게 됩니다.

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

});

express를 사용하는 경우 Express의 내장 기능을 사용하여 앱 내 경로와 모듈 간에 데이터를 공유하는 보다 간단한 방법이 있습니다.app.locals라는 객체가 있습니다.거기에 속성을 붙여 루트 내부에서 액세스 할 수 있습니다.이를 사용하려면 app.js 파일에서 mongo 연결을 인스턴스화하십시오.

var app = express();

MongoClient.connect('mongodb://localhost:27017/')
.then(client =>{
  const db = client.db('your-db');
  const collection = db.collection('your-collection');
  app.locals.collection = collection;
});
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // view engine setup
app.set('views', path.join(__dirname, 'views'));

데이터베이스 앱 는 이제 할 수 . 른 、 른 、 른 、 른 、 른른 this 。req.app.locals추가 모듈을 작성하거나 추가 모듈을 필요로 하지 않습니다.

app.get('/', (req, res) => {
  const collection = req.app.locals.collection;
  collection.find({}).toArray()
  .then(response => res.status(200).json(response))
  .catch(error => console.error(error));
});

이 방법을 사용하면 언제든지 데이터베이스 연결을 닫도록 선택하지 않는 한 앱 기간 동안 데이터베이스 연결을 열 수 있습니다.쉽게 액세스 할 수 있습니다.req.app.locals.your-collection추가 모듈을 작성할 필요가 없습니다.

연결 풀링을 구현하기 위한 가장 좋은 방법은 db 이름을 가진 글로벌 배열 변수를 하나 만드는 것입니다.이 변수에는 connection 객체가 반환됩니다.MongoClient그런 다음 데이터베이스에 연결할 때마다 연결을 다시 사용합니다.

  1. 고객님의 고객명Server.js정의하다var global.dbconnections = [];

  2. 서비스 이름 만들기connectionService.js두 가지 방법이 있습니다.getConnection그리고.createConnection사용자가 언제 전화를 걸면getConnection()글로벌 연결 변수에서 자세한 내용을 검색하여 이미 존재하는 경우 연결 세부 정보를 반환합니다.createConnection()및 연결 세부사항을 반환합니다.

  3. 다음을 사용하여 이 서비스를 호출합니다.<db_name>연결 개체가 이미 있는 경우 새 연결을 생성하여 사용자에게 반환합니다.

도움이 되었으면 좋겠다:)

여기 있습니다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;
} 

2021년에 Typescript에서 사용할 수 있는 것을 원하는 사람이 있다면 다음과 같이 하십시오.

import { MongoClient, Collection } from "mongodb";

const FILE_DB_HOST = process.env.FILE_DB_HOST as string;
const FILE_DB_DATABASE = process.env.FILE_DB_DATABASE as string;
const FILES_COLLECTION = process.env.FILES_COLLECTION as string;

if (!FILE_DB_HOST || !FILE_DB_DATABASE || !FILES_COLLECTION) {
  throw "Missing FILE_DB_HOST, FILE_DB_DATABASE, or FILES_COLLECTION environment variables.";
}

const client = new MongoClient(FILE_DB_HOST, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

class Mongoose {
  static FilesCollection: Collection;

  static async init() {
    const connection = await client.connect();
    const FileDB = connection.db(FILE_DB_DATABASE);
    Mongoose.FilesCollection = FileDB.collection(FILES_COLLECTION);
  }
}


Mongoose.init();

export default Mongoose;

요청이 너무 빨리 발생하면 (이전)Mongo.init()종료할 시간이 있습니다).이 때문에, 에러가 발생합니다.Mongoose.FilesCollection정의되지 않습니다.

import { Request, Response, NextFunction } from "express";
import Mongoose from "../../mongoose";

export default async function GetFile(req: Request, res: Response, next: NextFunction) {
  const files = Mongoose.FilesCollection;
  const file = await files.findOne({ fileName: "hello" });
  res.send(file);
}

예를 들어, 전화했을 경우files.findOne({ ... })그리고.Mongoose.FilesCollection정의되어 있지 않습니다.에러가 표시됩니다.

npm i express mongoose

mongodb.displaces

const express = require('express');
const mongoose =require('mongoose')
const app = express();

mongoose.set('strictQuery', true);
mongoose.connect('mongodb://localhost:27017/db_name', {
    useNewUrlParser: true, 
    useUnifiedTopology: true
})
.then(() => console.log('MongoDB Connected...'))
.catch((err) => console.log(err))

app.listen(3000,()=>{ console.log("Started on port 3000 !!!") })
node mongodb.js

다음 방법으로 접속을 최대한 쉽게 관리할 수 있습니다.

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

언급URL : https://stackoverflow.com/questions/10656574/how-do-i-manage-mongodb-connections-in-a-node-js-web-application

반응형