У mongoDB есть проблемы с повторным подключением или я делаю это неправильно?

Я использую nodejs и mongoDB - и у меня возникли проблемы с подключением.

ну, на самом деле" пробуждение " проблемы! Он отлично соединяется-это супер быстро, и я в целом доволен результатами.

моя проблема: если я какое-то время не использую соединение (я говорю while, потому что таймфрейм варьируется от 5+ минут), кажется, что он останавливается. Я не получаю события разъединения-он просто висит.

в итоге я получаю ответ, как ошибка: не удалось подключение к [ * .mongolab.com:*] - (*=значения в масках)

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

вот почему я думаю, что это "разбудить" вопросы.

грубый набросок кода:

Я не включил код - я не думаю, что это нужно. Он работает (кроме отсева соединения)

Примечание: Есть только одно "соединение" - я никогда его не закрываю. Я никогда не открываюсь.

Я использую Мангуст, socketio.

/* constants */

var mongoConnect = 'myworkingconnectionstring-includingDBname';


/* includes */

/* settings */

/* Schema */

var db = mongoose.connect(mongoConnect);

    /* Socketio */

io.configure(function (){
    io.set('authorization', function (handshakeData, callback) {

    });
});

io.sockets.on('connection', function (socket) {

});//sockets

io.sockets.on('disconnect', function(socket) {
    console.log('socket disconnection')
});

/* The Routing */

app.post('/login', function(req, res){  

});

app.get('/invited', function(req, res){

});

app.get('/', function(req, res){

});

app.get('/logout', function(req, res){

});

app.get('/error', function(req, res){

});

server.listen(port);
console.log('Listening on port '+port);

db.connection.on('error', function(err) {
    console.log("DB connection Error: "+err);
});
db.connection.on('open', function() {
    console.log("DB connected");
});
db.connection.on('close', function(str) {
    console.log("DB disconnected: "+str);
});

Я пробовал различные конфигурации здесь, как открытие и закрытие все время - я считаю, хотя, общий консенсус заключается в том, чтобы сделать, как я с одной открытой упаковкой много. ??

Я пробовал тестер соединений, который продолжает проверять состояние соединения... хотя это, кажется, говорят все нормально - проблема происходит.

У меня была эта проблема с первого дня. Я всегда принимал MongoDB с MongoLab. Проблема, по-видимому, хуже на localhost. Но у меня все еще есть проблема с Azure, и теперь nodejit.su.

Как это происходит везде-это должен быть я, MongoDB или mongolab.

кстати, у меня тоже был подобный опыт с драйвером php. (чтобы подтвердить это на nodejs, хотя)

было бы здорово помочь - даже если кто-то просто говорит "это нормально"

спасибо заранее

Роб

6 ответов


обновление: наша статья поддержки по этой теме (по сути, копия этого сообщения) переместилась в наше подключение устранение неполадок doc.

существует известная проблема, что сеть Azure IaaS обеспечивает тайм-аут простоя примерно тринадцать минут (эмпирически получено). Мы работаем с Azure, чтобы узнать, не можем ли мы сделать вещи более удобными для пользователя, но в то же время другие добились успеха, настроив свои параметры драйвера для работы вокруг вопрос.

максимальное время простоя соединения

наиболее эффективным решением, которое мы нашли при работе с Azure и нашими клиентами, было установить максимальное время простоя соединения ниже четырех минут. Идея состоит в том, чтобы заставить драйвер перерабатывать бездействующие соединения до того, как брандмауэр заставит проблему. Например, один клиент, который использует драйвер C#, устанавливает MongoDefaults.MaxConnectionIdleTime до одной минуты, и это прояснило их проблемы.

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);

сам код приложения не изменение, но теперь за кулисами водитель агрессивно перерабатывает бездействующие соединения. Результат можно увидеть и в журналах сервера: множество подключений во время простоя в приложении.

более подробная информация об этом подходе содержится в соответствующем потоке mongo-user,SocketException с помощью драйвера C# в azure.

Keepalive

вы также можете обойти эту проблему путем подключения тихо с какой-то keepalive. Это немного сложно реализовать, если ваш драйвер не поддерживает его из коробки, обычно используя TCP Keepalive. Если вам нужно свернуть свой собственный, не забудьте захватить каждое простое соединение из пула каждые пару минут и выдать простую и дешевую команду, возможно,пинг.

обработка разъединяет

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

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

но это не полностью решит проблему. У вас все еще есть вопрос о том, что делать с неудачной операцией, которая вызвала восстанавливать соединение. Автоматическое повторное подключение не повторяет автоматически неудачные операции. Это было бы опасно, особенно для писателей. Поэтому обычно возникает исключение, и приложение запрашивается для его обработки. Часто повторная попытка чтения-это не проблема. Но повторные попытки писать следует тщательно обдумать.

сеанс оболочки mongo ниже демонстрирует проблему. В оболочке mongo по умолчанию включено автоматическое повторное подключение. Я вставляю документ в коллекцию с именем stuff тогда найдите все документы в этом коллекция. Затем я установил таймер на тридцать минут и попробовал снова найти то же самое. Это не удалось, но оболочка автоматически подключилась, и когда я немедленно повторил свою находку, она работала так, как ожидалось.

% mongo ds012345.mongolab.com:12345/mydatabase -u *** -p *** 
MongoDB shell version: 2.2.2 
connecting to: ds012345.mongolab.com:12345/mydatabase 
> db.stuff.insert({}) 
> db.stuff.find() 
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") } 
> db.stuff.find() 
Fri Jan 18 13:29:28 Socket recv() errno:60 Operation timed out 192.168.1.111:12345 
Fri Jan 18 13:29:28 SocketException: remote: 192.168.1.111:12345 error: 9001 socket exception [1] server [192.168.1.111:12345] 
Fri Jan 18 13:29:28 DBClientCursor::init call() failed 
Fri Jan 18 13:29:28 query failed : mydatabase.stuff {} to: ds012345.mongolab.com:12345 
Error: error doing query: failed 
Fri Jan 18 13:29:28 trying reconnect to ds012345.mongolab.com:12345 
Fri Jan 18 13:29:28 reconnect ds012345.mongolab.com:12345 ok 
> db.stuff.find() 
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }

мы здесь, чтобы помочь

конечно, если у вас есть какие-либо вопросы, пожалуйста, свяжитесь с нами по адресу support@mongolab.com - ... Мы здесь, чтобы помочь.


Спасибо за помощь, ребята - мне удалось решить эту проблему как на localhost, так и на развернутом сервере.

вот мой теперь рабочий код подключения:

var MONGO = {
    username: "username",
    password: "pa55W0rd!",
    server: '******.mongolab.com',
    port: '*****',
    db: 'dbname',
    connectionString: function(){
        return 'mongodb://'+this.username+':'+this.password+'@'+this.server+':'+this.port+'/'+this.db;
    },
    options: {
        server:{
            auto_reconnect: true,
            socketOptions:{
                connectTimeoutMS:3600000,
                keepAlive:3600000,
                socketTimeoutMS:3600000
            }
        }
    }
};

var db = mongoose.createConnection(MONGO.connectionString(), MONGO.options);

db.on('error', function(err) {
    console.log("DB connection Error: "+err);
});
db.on('open', function() {
    console.log("DB connected");
});
db.on('close', function(str) {
    console.log("DB disconnected: "+str);
});

Я думаю, что самым большим изменением было использование "createConnection" над "connect" - я использовал это раньше, но, возможно, параметры помогают сейчас. Эта статья очень помогла http://journal.michaelahlers.org/2012/12/building-with-nodejs-persistence.html

Если честно я не слишком уверен в том, почему я добавил Эти параметры - как упоминалось @jareed, я также нашел некоторых людей, имеющих успех с "MaxConnectionIdleTime" - но, насколько я вижу, у драйвера javascript нет этой опции: это была моя попытка повторить поведение.

пока так хорошо-надеюсь, это кому-то поможет.

обновление: 18 апреля 2013 Примечание, это второе приложение с другой настройкой

теперь я думал, что у меня есть это решено, но проблема поднялась, это уродливая голова снова на другое приложение недавно-с тем же кодом подключения. Запутался!!!

однако настройка была немного другой...

это новое приложение было запущено в окне windows с помощью IISNode. поначалу я не считал это важным.

Я прочитал, что, возможно, были некоторые проблемы с mongo в Azure (@jareed), поэтому я переместил БД в AWS - все еще проблема сохранялась.

Так что я начал играть с этим объектом опций снова, читая довольно много на нем. Пришел к такому выводу:--3-->

options: {
    server:{
        auto_reconnect: true,
        poolSize: 10,
        socketOptions:{
            keepAlive: 1
        }
    },
    db: {
        numberOfRetries: 10,
        retryMiliSeconds: 1000
    }
}

Это было немного более образованным, что мои исходные параметры объекта Я состоянии. Однако-все равно ничего хорошего.

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

поэтому я переместил свое приложение в nodejitsu. низкий и вот моя связь осталась жива! Ву!

Так.... что это значит... понятия не имею! Что я знаю, так это то, что эти варианты, похоже, работают на Nodejitsu.... для меня.

Я считаю, что IISNode использует какой-то" навсегда " скрипт для поддержания приложения в живых. Теперь, чтобы быть справедливым, приложение не падает, чтобы это сработало, но я думаю, что должен быть какой-то "цикл приложений", который постоянно обновляется - так он может выполнять непрерывное развертывание (ftp-код, нет необходимости перезапускать приложение) - может быть, это фактор, но я просто думаю сейчас.

конечно, все это означает, что сейчас это не решено. Это все еще не решено. Это просто решается для меня в моей установке.


несколько рекомендаций для людей, все еще имеющих эту проблему:

  1. убедитесь, что вы используете последний клиент mongodb для узла.js. Я заметил значительные улучшения в этой области при миграции из v1.2.от x до v1.3.10 (последний на сегодня)

  2. вы можете передать объект options в MongoClient.соединять. Следующие параметры работали для меня при подключении из Azure в MongoLab:

    опции = { децибел: {}, сервер: { auto_reconnect: true, socketOptions: {keepAlive: 1} }, replSet: {}, mongos: {} };

    MongoClient.подключение (dbUrl, опции, функция (err, dbConn) { // ваш код });

  3. этот другой ответ, в котором я описываю, как справиться с "закрыть" событие, которое кажется более надежным. https://stackoverflow.com/a/20690008/446681


включить auto_reconnect Server такой:

var db = mongoose.connect(mongoConnect, {server: {auto_reconnect: true}});

соединение, которое вы открываете здесь, на самом деле представляет собой пул из 5 соединений (по умолчанию), поэтому вы правы, чтобы просто подключиться и оставить его открытым. Я предполагаю, что вы периодически теряете связь с mongolab, и ваши связи умирают, когда это происходит. Надеюсь, включение auto_reconnect решает, что.


увеличение таймаутов может помочь.

  • "socketTimeoutMS" : сколько времени может занять отправка или получение сокета перед тем, как выйти из игры.
  • "wTimeoutMS": он контролирует, сколько миллисекунд сервер ждет напишите беспокойство, чтобы быть удовлетворены.
  • "connectTimeoutMS" : сколько времени может потребоваться для открытия соединения до тайм-аута в миллисекундах.

    $m = новый MongoClient ("mongodb: / / 127.0.0.1:27017", array ("connect" = > TRUE, "connectTimeoutMS" =>10, "socketTimeoutMS" =>10, "wTimeoutMS"=>10));

        $db= $m->mydb;
        $coll = $db->testData;
        $coll->insert($paramArr);
    

У меня была похожая проблема периодически отключается от MongoDB. Это исправили две вещи:

  1. убедитесь, что ваш компьютер никогда не спит (это убьет ваше сетевое соединение).
  2. обход маршрутизатора / брандмауэра (или настроить его должным образом, что я еще не понял, как это сделать).