¿MongoDB tiene problemas de reconexión o lo estoy haciendo mal?


Estoy usando nodejs y un MongoDB - y estoy teniendo algunos problemas de conexión.

Bueno, en realidad "despertar" cuestiones! Se conecta perfectamente bien - es súper rápido y en general estoy contento con los resultados.

Mi problema: Si no uso la conexión por un tiempo (digo mientras, porque el marco de tiempo varía 5+ minutos) parece estancarse. No recibo eventos de desconexión disparados, simplemente se cuelga.

Eventualmente obtengo una respuesta como Error: failed to connect to [ * .mongolab.com:*] - (*=valores enmascarados)

Un reinicio rápido de la aplicación, y la conexión es genial de nuevo. A veces, si no reinicio la aplicación, puedo actualizarla y reconectarla felizmente.

Esta es la razón por la que creo que se trata de cuestiones de "despertar".

Resumen del código:

No he incluido el código - no creo que sea necesario. Funciona (aparte del abandono de la conexión)

Cosas a tener en cuenta: Solo hay una "conexión" - nunca la cierro. Me nunca vuelva a abrir.

Estoy usando mangosta, 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);
});

He probado varias configuraciones aquí, como abrir y cerrar todo el tiempo; sin embargo, creo que el consenso general es hacer lo que hago con una envoltura abierta del lote. ??

He probado un comprobador de conexión, que sigue comprobando el estado de la conexión... a pesar de que esto parece decir que todo está bien, el problema sigue ocurriendo.

He tenido este problema desde el primer día. Siempre he acogido el MongoDB con MongoLab. El problema parece ser peor en localhost. Pero todavía tengo el problema en Azure y ahora nodejit.su.

Como sucede en todas partes - debe ser yo, MongoDB, o mongolab.

Por cierto, también he tenido una experiencia similar con el controlador php. (para confirmar esto es en nodejs aunque)

Sería genial para algo de ayuda, incluso si alguien simplemente dice "esto es normal"

Gracias de antemano

Rob

Author: jared, 2012-12-21

6 answers

ACTUALIZAR : Nuestro artículo de soporte para este tema (esencialmente una copia de esta publicación) se ha trasladado a nuestro documento de solución de problemas de conexión.

Existe un problema conocido de que la red de Azure IaaS impone un tiempo de espera de inactividad de aproximadamente trece minutos (al que se llegó empíricamente). Estamos trabajando con Azure para ver si podemos hacer las cosas más fáciles de usar, pero mientras tanto otros han tenido éxito al configurar sus opciones de controlador para solucionar el problema.

Max tiempo de inactividad de la conexión

La solución más efectiva que hemos encontrado al trabajar con Azure y nuestros clientes ha sido establecer el tiempo máximo de inactividad de la conexión por debajo de cuatro minutos. La idea es hacer que el controlador recicle las conexiones inactivas antes de que el firewall fuerce el problema. Por ejemplo, un cliente, que está usando el controlador de C#, estableció MongoDefaults.MaxConnectionIdleTime a un minuto y aclaró sus problemas.

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);

El código de la aplicación en sí no cambió, pero ahora detrás de las escenas el controlador recicla agresivamente las conexiones inactivas. El resultado también se puede ver en los registros del servidor: mucha pérdida de conexión durante los períodos de inactividad en la aplicación.

Hay más detalles sobre este enfoque en el subproceso mongo-user relacionado, SocketException usando el controlador C# en azure.

Keepalive

También puede solucionar el problema haciendo que sus conexiones estén menos inactivas con algún tipo de keepalive. Esto es un poco difícil de implementar a menos que su conductor admite fuera de la caja, generalmente aprovechando TCP Keepalive. Si usted necesita rodar su propia, asegúrese de tomar cada conexión inactiva de la piscina cada par de minutos y emitir algún comando simple y barato, probablemente un ping .

Manejo de desconexiones

Las desconexiones pueden ocurrir de vez en cuando, incluso sin una configuración agresiva del firewall. Antes de entrar en producción, debe asegurarse de manejarlos correctamente.

Primero, asegúrese para habilitar la reconexión automática. La forma de hacerlo varía de un controlador a otro, pero cuando el controlador detecta que una operación falló debido a que la conexión era incorrecta al activar la reconexión automática, le dice al controlador que intente reconectarse.

Pero esto no resuelve completamente el problema. Todavía tiene el problema de qué hacer con la operación fallida que activó la reconexión. La reconexión automática no reintenta automáticamente las operaciones fallidas. Eso sería peligroso, especialmente para los escritores. Tan generalmente un se lanza la excepción y se le pide a la aplicación que la maneje. A menudo volver a leer es una obviedad. Pero volver a escribir debe ser considerado cuidadosamente.

La sesión de shell de mongo a continuación muestra el problema. El shell de mongo por defecto tiene activada la reconexión automática. Inserto un documento en una colección llamada stuff y luego encuentro todos los documentos en esa colección. Luego configuré un temporizador durante treinta minutos e intenté el mismo hallazgo nuevamente. Falló, pero el shell se reconectó automáticamente y cuando inmediatamente volví a probar mi hallazgo funcionó como se esperaba.

% 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") }

Estamos aquí para ayudar

Por supuesto, si tiene alguna pregunta, no dude en contactarnos en [email protected] Estamos aquí para ayudar.

 27
Author: jared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-04 21:08:38

Gracias por toda la ayuda chicos - he logrado resolver este problema tanto en localhost y desplegado a un servidor en vivo.

Aquí está mi código de conexión que funciona ahora:

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

Creo que el mayor cambio fue usar "createConnection" sobre "connect" - ya había usado esto antes, pero tal vez las opciones ayuden ahora. Este artículo ayudó mucho http://journal.michaelahlers.org/2012/12/building-with-nodejs-persistence.html

Si soy honesto, no estoy demasiado seguro de por qué he agregado esas opciones-como se mencionó por @jareed, también encontré algunas personas que tienen éxito con "MaxConnectionIdleTime" - pero por lo que puedo ver el controlador de javascript no tiene esta opción: este fue mi intento de intentar replicar el comportamiento.

Hasta ahora todo bien - espero que esto ayude a alguien.

ACTUALIZACIÓN: 18 de abril 2013 nota, esta es una segunda aplicación con una configuración diferente

Ahora pensé que tenía esto resuelto, pero el problema se elevó. otra aplicación recientemente - con el mismo código de conexión. Confundido!!!

Sin embargo, la configuración fue ligeramente diferente {

Esta nueva aplicación se estaba ejecutando en un cuadro de Windows utilizando IISNode. Inicialmente no vi esto como significativo.

Leí que posiblemente hubo algunos problemas con mongo en Azure (@jareed), así que moví la base de datos a AWS, pero el problema persistió.

Así que empecé a jugar con ese objeto de opciones de nuevo, leyendo bastante sobre él. Venir a esta conclusión:

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

Eso fue un poco más educado que mis opciones originales objeto i estado. Sin embargo, todavía no es bueno.

Ahora, por alguna razón tuve que salir de ese cuadro de Windows (algo que ver con un módulo que no se compila en él) - era más fácil de mover que pasar otra semana tratando de conseguir que funcione.

Así que moví mi aplicación a nodejitsu. Baja y he aquí mi conexión se mantuvo viva! Woo!

Así..... ¿qué significa esto no no tengo idea! Lo que hago saber es es esas opciones parecen funcionar en Nodejitsu.... para mí.

Creo que IISNode usa algún tipo de script "para siempre" para mantener viva la aplicación. Ahora, para ser justos, la aplicación no se bloquea para que esto entre, pero creo que debe haber algún tipo de "ciclo de aplicación" que se actualiza constantemente, así es como puede hacer un despliegue continuo (código ftp arriba, no hay necesidad de reiniciar la aplicación), tal vez esto es un factor; pero solo estoy adivinando ahora.

Por supuesto todo esto significa ahora, es que esto no está resuelto. Es aún no resuelto. Se acaba de resolver para mí en mi configuración.

 18
Author: rob_james,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-17 12:00:52

Un par de recomendaciones para las personas que aún tienen este problema:

  1. Asegúrese de que está utilizando el último cliente mongodb para node.js. Noté mejoras significativas en esta área al migrar desde v1.2.x a v1.3.10 (la última a partir de hoy)

  2. Puede pasar un objeto options al MongoClient.conectar. Las siguientes opciones me funcionaron al conectarme de Azure a MongoLab:

    Opciones = { db: {}, servidor: { auto_reconectar: true, socketOptions: {keepAlive: 1} }, replSet: {}, mongos: {} };

    MongoClient.conectar (dbUrl, opciones, función (err, dbConn) { // su código });

  3. Vea esta otra respuesta en la que describo cómo manejar el evento 'cercano' que parece ser más confiable. https://stackoverflow.com/a/20690008/446681

 6
Author: Hector Correa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:19:26

Activar el auto_reconnect Server opción como esta:

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

La conexión que estás abriendo aquí es en realidad un grupo de 5 conexiones (de forma predeterminada), por lo que tienes razón en conectarte y dejarla abierta. Mi conjetura es que intermitentemente pierdes conectividad con mongolab y tus conexiones mueren cuando eso ocurre. Con suerte, habilitar auto_reconnect resuelve eso.

 1
Author: JohnnyHK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-22 03:21:27

Aumentar los tiempos de espera puede ayudar.

  • "socketTimeoutMS" : Cuánto tiempo puede tardar un envío o recepción en un socket antes de perder el tiempo.
  • "wTimeoutMS": Controla cuántos milisegundos espera el servidor la preocupación de escribir para ser satisfecho.
  • "connectTimeoutMS": Cuánto tiempo puede tardar una conexión en abrirse antes de perder el tiempo en milisegundos.

    $m = nuevo 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);
    
 1
Author: djebel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-18 10:53:24

Tuve un problema similar al estar desconectado de MongoDB periódicamente. Hacer dos cosas lo arregló:

  1. Asegúrese de que su computadora nunca duerma (eso matará su conexión de red).
  2. Omitir su router/firewall (o configurarlo correctamente, que no he descubierto cómo hacer todavía).
 0
Author: Mike M. Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:06:52