Реплика mongodb устанавливает соединение в контейнере Docker - PullRequest
0 голосов
/ 14 мая 2018

Я создал набор реплик mongodb в 3 виртуальных ящиках vms, manasger1, worker1, worker2. каждый набор реплик имеет свои собственные контейнеры. Набор реплик работает нормально, и я могу войти на серверы:

docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'
MongoDB shell version v3.6.4
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.4
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
rs1:PRIMARY> use medmart_db
switched to db medmart_db
rs1:PRIMARY> db.providers.findObe()
2018-05-14T17:46:38.844+0000 E QUERY    [thread1] TypeError: db.providers.findObe is not a function :
@(shell):1:1
rs1:PRIMARY> db.providers.findOne()
{
    "_id" : ObjectId("56ddb50c230e405eafaf7781"),
    "provider_id" : 6829973073,

Когда я запускаю свое приложение nodejs, оно подключается к набору реплик. Проблема в том, что когда я создаю контейнер для своего приложения, я получаю следующее исключение, мой контейнер останавливается, и я больше не могу подключиться к набору реплик PRIMARY, а вместо этого к дополнительному.

(node:16) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [worker2:27017] on first connect [MongoNetworkError: connection 5 to worker2:27017 timed out]
     at Pool.<anonymous> (/home/nupp/app/node_modules/mongoose/node_modules/mongodb-core/lib/topologies/server.js:505:11)
     at Pool.emit (events.js:182:13)
     at Connection.<anonymous> (/home/nupp/app/node_modules/mongoose/node_modules/mongodb-core/lib/connection/pool.js:329:12)
     at Object.onceWrapper (events.js:273:13)
     at Connection.emit (events.js:182:13)
     at Socket.<anonymous> (/home/nupp/app/node_modules/mongoose/node_modules/mongodb-core/lib/connection/connection.js:256:10)
     at Object.onceWrapper (events.js:273:13)
     at Socket.emit (events.js:182:13)
     at Socket._onTimeout (net.js:447:8)
     at ontimeout (timers.js:427:11)
     at tryOnTimeout (timers.js:289:5)
     at listOnTimeout (timers.js:252:5)
     at Timer.processTimers (timers.js:212:10)
 (node:16) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
 (node:16) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Я открыл справку о проблеме с mongoose за помощью, но их решение не работает (они попросили меня изменить IP-адрес на доменное имя, но я все еще получаю ту же ошибку).

Мой модуль подключения:

'use strict';
const mongoose = require('mongoose');
const getURL = (options) => {
    const url = options.servers.reduce((accumulator, current) => {
        accumulator += current+',';
        return accumulator;
    },`mongodb://${options.user}:${options.pass}@`);    
    return `${url.substr(0,url.length-1)}/${options.db}?replicaSet=${options.repl}&authSource=admin`;
}
const connect = (config, mediator) => {
    mediator.once('boot.ready', () => {
        const options = {
            native_parser: true,
            poolSize: 5,
            user: config.user,
            pass: config.pass,
            promiseLibrary: global.Promise,
            autoIndex: false, 
            reconnectTries: 30, 
            reconnectInterval: 500, 
            bufferMaxEntries: 0,
            connectWithNoPrimary: true ,
            readPreference: 'ReadPreference.SECONDARY_PREFERRED',
        };              
        mongoose.connect(getURL(config), options);
        mongoose.connection.on('error', (err) => {  
            mediator.emit('db.error', err);
        });
        mongoose.connection.on('connected', () => {
            mediator.emit('db.ready', mongoose);
        });
    });
};
module.exports = Object.assign({},{connect});

Мой конфигурационный файл:

'use strict';
const serverConfig = {
    port: 3000, 
};
const dbConfig = {
  db: 'xxxxxxx',
  user: 'xxxxxx',
  pass: 'xxxxxxx',
  repl: 'rs1',
  servers: (process.env.DB_SERVERS) ? process.env.DB_SERVERS.split(' ') : ['192.168.99.100:27017','192.168.99.101:27017','192.168.99.102:27017'],
};
module.exports = Object.assign({},{dbConfig, serverConfig});

1 Ответ

0 голосов
/ 15 мая 2018

Итак, есть несколько шагов для решения этой проблемы. Прежде всего, это тот факт, что файл hosts на машинах virtualBox должен быть обновлен, чтобы иметь IP-адреса доменов mongodb. Для этого:

> docker-machine ssh manager1
docker@manager1:~$ sudo vi /etc/hosts
#add the following
192.168.99.100 manager1
192.168.99.101 worker1
192.168.99.102 worker2

Повторите для работник1 и работник2. Если, добавив следующее, вы хороши, тогда пропустите вторую часть. Далее, если вы получите следующую ошибку:

Error: ERROR::providers-service::model::ProviderModel::getProviderById: TypeError: Cannot read property 'wireProtocolHandler' of null
     at cb (/home/nupp/app/src/model/ProviderModel.js:182:13)
     at /home/nupp/app/node_modules/mongoose/lib/model.js:4161:16
     at Immediate.Query.base.findOne.call (/home/nupp/app/node_modules/mongoose/lib/query.js:1529:14)
     at Immediate.<anonymous> (/home/nupp/app/node_modules/mquery/lib/utils.js:119:16)
     at runCallback (timers.js:696:18)
     at tryOnImmediate (timers.js:667:5)
     at processImmediate (timers.js:649:5)

Удалите все опции для mongoose.connect. Вот как выглядит моя сейчас:

mediator.once('boot.ready', () => {
        const options = {};         
        mongoose.connect(getURL(config), options);
        mongoose.connection.on('error', (err) => {  
            mediator.emit('db.error', err);
        });
        mongoose.connection.on('connected', () => { 
            mediator.emit('db.ready', mongoose);
        });
    });

Надеюсь, мое решение может помочь кому-то еще. Мне понадобилось несколько долгих дней, чтобы наконец понять это.

...