Предпочтение соединения Mongodb, на запрос или запуск сервера [дубликат]

Если вы используете vscode, вы можете использовать мое расширение csharp2ts , которое делает именно это.

Вы просто выбираете вставленный код C # и запускаете команду Convert C# to TypeScript из палитры команд Пример преобразования:

public class Person
{
    /// 
    /// Primary key
    /// 
    public int Id { get; set; }

    /// 
    /// Person name
    /// 
    public string Name { get; set; }
}

-

export interface Person
{
    /**Primary key */
    Id : number;

    /**Person name */
    Name : string;
}

217
задан Peter Mortensen 15 January 2017 в 10:47
поделиться

9 ответов

Основной коммиттер node-mongodb-native говорит :

Вы открываете make MongoClient.connect один раз, когда ваше приложение загружается и повторно использует объект db. Это не единичный пул соединений каждый .connect создает новый пул соединений.

Итак, чтобы напрямую ответить на ваш вопрос, повторно используйте объект db, полученный в результате MongoClient.connect (). Это дает вам объединение и обеспечивает заметное увеличение скорости по сравнению с открытием / закрытием соединений при каждом действии db.

375
ответ дан Max 20 August 2018 в 10:35
поделиться
  • 1
    Должен быть отмечен как правильный ответ. – Thomas Bratt 22 April 2013 в 14:16
  • 2
    Ссылка на MongoClient.connect () mongodb.github.io/node-mongodb-native/driver-articles/… – AndrewJM 24 July 2013 в 18:19
  • 3
    Это правильный ответ. Принятый ответ очень не прав, поскольку он говорит, чтобы открыть пул соединений для каждого запроса, а затем закрыть его после этого. Ужасная архитектура. – Saransh Mohapatra 13 August 2013 в 15:56
  • 4
    Это правильный ответ. Мой бог воображает, что мне приходится открывать и закрывать каждый раз, когда я делаю что-то, это будет 350K в час только для моих вставок! Это похоже на атаку моего собственного сервера. – Maziyar 30 September 2013 в 02:12
  • 5
    @Cracker: если у вас есть экспресс-приложение, вы можете сохранить объект db в req.db с помощью этого промежуточного программного обеспечения: github.com/floatdrop/express-mongo-db – floatdrop 8 August 2014 в 19:15

Я реализовал ниже код в своем проекте для реализации пула соединений в моем коде, чтобы он создавал минимальное соединение в моем проекте и повторно использовал доступное соединение

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

});
1
ответ дан Aditya Parmar 20 August 2018 в 10:35
поделиться

Я использую общий пул с соединениями redis в своем приложении - я очень рекомендую его. Его общий и я определенно знаю, что он работает с mysql, поэтому я не думаю, что у вас будут проблемы с ним и mongo

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

6
ответ дан ControlAltDel 20 August 2018 в 10:35
поделиться
  • 1
    Mongo уже подключает пул соединений в драйвере, однако я сопоставил свои подключения mongo в интерфейсе, который соответствует узловому пулу, таким образом все мои подключения следуют одному и тому же шаблону, хотя в случае mongo очистка не фактически запускать что-либо. – Tracker1 11 August 2014 в 21:49

Вы должны создать соединение в качестве службы, а затем повторно использовать его, когда это необходимо.

// 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
2
ответ дан LeeKaD 20 August 2018 в 10:35
поделиться
  • 1
    Если mongo не удалось подключиться, MongoClient.close () выдает ошибку. Но хорошее решение для оригинальной проблемы. – Himanshu 15 November 2017 в 08:09

Если у вас есть Express.js, вы можете использовать express-mongo-db для кэширования и совместного использования соединения MongoDB между запросами без пула (поскольку принятый ответ говорит, что это правильный способ обмена соединение).

Если нет - вы можете посмотреть его исходный код и использовать его в другой структуре.

29
ответ дан Peter Mortensen 20 August 2018 в 10:35
поделиться
  • 1
    Это создает одно соединение с базой данных ... если вы хотите использовать пулы, которые вы должны создавать / закрывать при каждом использовании – amcdnl 15 December 2015 в 16:01
  • 2
    Вне темы, это самый странный файл NodeJS, который я когда-либо видел. – Hobbyist 12 June 2016 в 04:04
  • 3
    Обновление с 5.x: var option = {numberOfRetries: 5, auto_reconnect: true, poolSize: 40, connectTimeoutMS: 30000}; – Blair 11 July 2018 в 01:40

Лучший подход к реализации пула соединений - это создать одну глобальную переменную массива, которая будет содержать имя db с объектом соединения, возвращаемым MongoClient, и затем повторно использовать это соединение, когда вам нужно связаться с базой данных.

  1. In ваш Server.js определит var global.dbconnections = [];
  2. Создайте имя именования сервисовService.js. Он будет иметь 2 метода getConnection и createConnection. Поэтому, когда пользователь будет вызывать getConnection (), он найдет детали в глобальной переменной соединения и вернет данные соединения, если уже существует, иначе он вызовет createConnection () и вернет сведения о соединении.
  3. Вызовите эту службу, используя имя db_ и будет возвращать объект соединения, если он уже имеет другое, он создаст новое соединение и вернет его вам.

Надеюсь, что это поможет:)

Вот код 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;
} 
1
ответ дан RRPatel 20 August 2018 в 10:35
поделиться

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

Проверьте источник Mongoose. Они открывают соединение и привязывают его к объекту модели, поэтому, когда требуется объект модели, в DB создается соединение. Драйвер заботится о пуле соединений.

3
ответ дан srquinn 20 August 2018 в 10:35
поделиться

Управляйте пулами соединений mongo в одном автономном модуле. Такой подход обеспечивает два преимущества. Во-первых, он сохраняет ваш код модульным и легче тестировать. Во-вторых, вы не должны смешивать соединение с базой данных в объекте запроса, который НЕ является местом для объекта подключения к базе данных. (Учитывая характер 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;
}
9
ответ дан Stewart 20 August 2018 в 10:35
поделиться
  • 1
    очень полезно, именно то, что я искал! – agui 9 May 2017 в 08:27
  • 2
    Еще лучше, вы могли бы просто избавиться от функции connect () и проверить функцию get (), чтобы узнать, является ли соединение нулевым и вызовите соединение для вас, если оно есть. Получите () всегда возвращайте обещание. Вот как я управляю своим подключением, и он отлично работает. Это использование одноэлементного шаблона. – java-addict301 2 June 2017 в 11:52
  • 3
    @ java-addict301 Хотя этот подход обеспечивает более оптимизированный API, он имеет два недостатка. Первое заключается в том, что нет определенного способа проверки ошибок подключения. Вы должны были бы справиться с этим, когда бы вы ни называли get. Мне нравится рано работать с соединениями с базой данных, и обычно я не позволяю загружать приложение без подключения к базе данных. Другая проблема - пропускная способность. Поскольку у вас нет активного соединения, вам, возможно, придется подождать немного дольше при первом вызове get (), с которым вы не будете контролировать. Может исказить ваши показатели отчетности. – Stewart 5 June 2017 в 03:23
  • 4
    @Stewart Способ структурирования приложений / сервисов - это, как правило, получение конфигурации из базы данных при запуске. Таким образом, приложение не будет запущено, если база данных недоступна. Кроме того, поскольку первый запрос всегда при запуске, нет никаких проблем с метриками с этим дизайном. Также удалите исключение соединения с одним местом в одноэлементном режиме с явной ошибкой, с которой он не может подключиться. Так как приложение должно поймать ошибки базы данных при использовании соединения в любом случае, это не приведет к какой-либо дополнительной обработке inline. – java-addict301 6 June 2017 в 00:31
  • 5
    @Stewart Как бы вы справлялись с тем случаем, когда соединение mongo умирает на более позднем этапе после подключения? Все вызовы метода get () не будут выполняться в этом сценарии до тех пор, пока приложение узла не будет перезапущено. – Ayan 22 August 2017 в 14:08
30
ответ дан Peter Mortensen 31 October 2018 в 08:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: