Подключение Мангуста к набору реплик

#node.js #mongodb #mongoose #replicaset

#node.js #mongodb #mongoose #набор реплик

Вопрос:

Я попытался подключиться к набору реплик MongoDB через mongoose. Я использовал эту ссылку.
Конфигурационный json:

 "mongoose": {
   "uri": "mongodb://localhost:27022/chat,localhost:27021,localhost:27020",
   "options": {
       "replset": { "rs_name": "rs0" },
       "server": {
           "poolSize": 3,
           "socketOptions": {
               "keepAlive": 1
           }
       }
    }
}
  

Подключение Mongoose:

 var mongoose = require('mongoose');
mongoose.connect(config.get('mongoose:uri'), config.get('mongoose:options'));
  

И после запуска приложения я получил исключение:

 Error: host must be specified [undefined]
at new exports.ConnectionPool (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesmongodblibmongodbconnectionconnection_pool.js:18:11)
at Server.connect (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesmongodblibmongodbconnectionserver.js:335:25)
at Db.open (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesmongodblibmongodbdb.js:264:23)
at MongoStore._open_database (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesconnect-mongolibconnect-mongo.js:174:15)
at MongoStore._get_collection (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesconnect-mongolibconnect-mongo.js:169:14)
at MongoStore.get (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesconnect-mongolibconnect-mongo.js:213:10)
at Object.session [as handle] (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesconnectnode_modulesexpress-sessionindex.js:215:11)
at next (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesconnectlibproto.js:194:15)
at Object.module.exports [as handle] (c:Userslor1anDownloadsprj_chat-masterprj_chat-mastermiddlewareresExtensions.js:21:2)
at next (c:Userslor1anDownloadsprj_chat-masterprj_chat-masternode_modulesconnectlibproto.js:194:15)
  

База данных: чат, основной сервер: localhost: 27022.

Также я попытался удалить два других сервера (сохранив только основной в config json), и я увидел, что он знает о вторичных серверах (я использовал журнал). Я думаю, что речь идет о метаданных mongodb. Но когда я выключаю первичный, он завершает свою работу (неудивительно), он мне нужен, чтобы вместо него можно было использовать вторичный.
Есть идеи?

Ответ №1:

Мы используем это:

 if(config.db.indexOf('replicaSet') > - 1) {
  dbOptions = {
    db: {native_parser: true},
    replset: {
      auto_reconnect:false,
      poolSize: 10,
      socketOptions: {
        keepAlive: 1000,
        connectTimeoutMS: 30000
      }
    },
    server: {
      poolSize: 5,
      socketOptions: {
        keepAlive: 1000,
        connectTimeoutMS: 30000
      }
    }
  };
}

var db = mongoose.connect(config.db, dbOptions);
  

где

 config.db =  'mongodb://USER:PW@host1:port1,host2:port2/DBNAME?replicaSet=RSNAME'
  

Автоматическое восстановление отключено согласно https://team.goodeggs.com/reconnecting-to-mongodb-when-mongoose-connect-fails-at-startup-83ca8496ca02

Комментарии:

1. @lor1an Как указано в этом ответе, ваше имя базы данных должно быть после списка портов host:. Итак, ваша строка подключения должна быть: mongodb://localhost:27022,mongodb://localhost:27021,mongodb://localhost:27020/chat

2. Обратите внимание, что keepAlive — это число, а не логическое значение, которое представляет количество мс, в течение которых соединение должно истекать, пока не будет установлено новое соединение. По этой причине установка значения 1 — очень плохая идея, потому что mongoose будет создавать новые соединения, когда на самом деле этого не должно быть.

3. @arasmussen да, но я думаю, что connectTimeoutMS — это количество МС, в течение которого соединение должно истекать, пока не будет установлено новое соединение. но я не знаю, что это такое, и, кроме того, маликс, не могли бы вы сказать мне, почему мы должны установить auto_reconnect: как false ??

4. тогда почему вы установили значение auto_reconnect false ??

5. исправлено @UpTheCreek

Ответ №2:

У меня тоже были проблемы с этим. Что я узнал из этого опыта, так это:

Блок «сервер» вызывается только тогда, когда URI соединения содержит одно некластеризованное соединение (иначе говоря, одну строку подключения).

Блок «replset» вызывается только тогда, когда URL-адрес соединения содержит список строк соединения, разделенных запятыми (он же набор репликации).

 var options = {

    db: {
        native_parser: true
    },

    // This block gets run for a non replica set connection string (eg. localhost with a single DB)
    server: {
        poolSize: 5,
        reconnectTries: Number.MAX_VALUE,
        ssl: false,
        sslValidate: false,
        socketOptions: {
            keepAlive: 1000,
            connectTimeoutMS: 30000
        }
    },

    // This block gets run when the connection string indicates a replica set (comma seperated connections)
    replset: {
        auto_reconnect: false,
        poolSize: 10,
        connectWithNoPrimary: true,
        ssl: true,
        sslValidate: false,
        socketOptions: {
            keepAlive: 1000,
            connectTimeoutMS: 30000
        }
    }
};
  

Этот блок работал как на локальном хосте, так и на рабочей среде.
Надеюсь, это поможет.

Комментарии:

1. Спасибо. Вы ответили на основные вопросы, над которыми я размышлял.

2. В документации не очень понятно об этом — я узнал методом проб и ошибок..

3. Да, документация по параметрам подключения monodb js действительно может быть улучшена.

Ответ №3:

Вероятно, ваша строка подключения недействительна. Вы должны предоставить URI для каждого члена набора реплик:

"uri": "mongodb://db0.example.com:27017,db1.example.com:27017,db2.example.com:27017/admin?replicaSet=myRepl"

Вы должны проверить раздел подключения к набору реплик в документации Mongoose.

Ответ №4:

 # mongoose connect secondary replicateSet

<pre>
let url = 'mongodb://mongo01:1001,mongo02:1002/db_name?replicaSet=xxx-replica' 
// 1 

let conn = mongoose.createConnection(url, {user:'xxx', pass:'xxx', autoIndex: false, replset: {readPreference: 'secondary'}});

// 2  

let conn = mongoose.createConnection(url, {user:'xxx', pass:'xxx', autoIndex: false});
let schema =  new mongoose.Schema({},{read:'secondary'});
let model = conn.model(modelName, schema);

//3
let conn = mongoose.createConnection(url, {user:'xxx', pass:'xxx', autoIndex: false};
let schema = new mongoose.Schema({});
let model = conn.model(modelName, schema);
model.find().read('secondary').then(info => {});

</pre>
  

Комментарии:

1. Дополнительная информация сделает ваш ответ лучше. Хотя этот блок кода отвечает на вопрос.