web-dev-qa-db-fra.com

Est-ce que mongoDB a des problèmes de reconnexion ou est-ce que je me trompe?

J'utilise nodejs et une mongoDB - et j'ai des problèmes de connexion.

En fait, les problèmes de "réveil"! Il se connecte parfaitement - est très rapide et je suis généralement satisfait du résultat.

Mon problème: Si je n'utilise pas la connexion pendant un certain temps (je dis pendant, car le délai varie de plus de 5 minutes), il semble caler. Je ne reçois pas d’événements de déconnexion, il se bloque. 

Finalement, je reçois une réponse du type Erreur: impossible de se connecter à [* .mongolab.com: *] - (* = valeurs masquées)

Un redémarrage rapide de l'application et la connexion est à nouveau excellente. Parfois, si je ne redémarre pas l'application, je peux l'actualiser et la reconnecter avec joie.

C'est pourquoi je pense que ce sont des problèmes de "réveil".

Ebauche de code:

Je n'ai pas inclus le code - je ne pense pas que ce soit nécessaire. Cela fonctionne (en dehors de la perte de connexion)

Choses à noter: Il y a juste celui "connectez" - je ne le ferme jamais. Je ne rouvre jamais.

J'utilise la mangouste, 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);
});

J'ai essayé diverses configurations ici, comme ouvrir et fermer tout le temps - je pense cependant, le consensus général est de faire comme moi avec une seule ouverture pour envelopper le lot. ??

J'ai essayé un testeur de connexion qui vérifie constamment l'état de la connexion ... même si cela semble indiquer que tout va bien, le problème persiste.

J'ai eu ce problème depuis le premier jour. J'ai toujours hébergé MongoDB avec MongoLab ..__ Le problème semble être pire sur localhost. Mais j'ai toujours le problème sur Azure et maintenant sur nodejit.su.

Comme cela arrive partout - ce doit être moi, MongoDB ou mongolab.

Incidemment, j'ai eu une expérience similaire avec le pilote php aussi. (pour confirmer que c'est sur nodejs cependant)

Ce serait bien d'avoir de l'aide, même si quelqu'un dit simplement "c'est normal"

merci d'avance

Rob

26
rob_james

UPDATE: notre article de support sur ce sujet (essentiellement une copie de ce message) a été déplacé vers notre document de dépannage de connexion .

Il existe un problème connu selon lequel le réseau Azure IaaS impose un délai d'inactivité d'environ treize minutes (arrivé de manière empirique). Nous travaillons avec Azure pour voir si nous ne pouvons pas rendre les choses plus conviviales, mais entre-temps, d’autres ont réussi à configurer leurs options de pilote pour résoudre le problème.

Durée maximale d'inactivité de la connexion

La solution de contournement la plus efficace que nous ayons trouvée en travaillant avec Azure et nos clients a été de définir le temps d'inactivité maximal de la connexion en dessous de quatre minutes. L'idée est de faire en sorte que le pilote recycle les connexions inactives avant que le pare-feu ne force le problème. Par exemple, un client qui utilise le pilote C # a défini MongoDefaults.MaxConnectionIdleTime sur une minute pour résoudre ses problèmes.

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);

Le code de l'application en lui-même n'a pas changé, mais maintenant en coulisse, le pilote recycle agressivement les connexions inactives. Le résultat est également visible dans les journaux du serveur: de nombreuses pertes de connexion pendant les périodes d'inactivité dans l'application.

Il existe plus de détails sur cette approche dans le thread mongo-user associé, SocketException à l'aide du pilote C # sur Azure .

Rester en vie

Vous pouvez également contourner le problème en rendant vos connexions moins inactives avec une sorte de keepalive . C'est un peu délicat à implémenter à moins que votre pilote ne le prenne en charge immédiatement, généralement en tirant parti de TCP Keepalive . Si vous avez besoin de lancer la vôtre, assurez-vous de saisir chaque connexion inactive du pool toutes les deux minutes et émettez une commande simple et peu coûteuse, probablement un ping .

Traitement des déconnexions

Des déconnexions peuvent se produire de temps en temps, même sans configuration de pare-feu agressive. Avant de commencer la production, vous voulez être sûr de les manipuler correctement.

Commencez par activer la reconnexion automatique. La procédure à suivre varie d’un pilote à l’autre, mais lorsque le pilote détecte qu’une opération a échoué parce que la connexion était mauvaise, l’activation de la reconnexion automatique indique au pilote de tenter de se reconnecter.

Mais cela ne résout pas complètement le problème. Vous avez toujours le problème de savoir quoi faire avec l'opération ayant échoué qui a déclenché la reconnexion. La reconnexion automatique ne relance pas automatiquement les opérations ayant échoué. Ce serait dangereux, surtout pour les écritures. Alors généralement, une exception est levée et l'application est invitée à la gérer. Réessayer souvent de lire est une évidence. Mais réessayer écrit devrait être soigneusement considéré.

La session de shell mongo ci-dessous illustre le problème. Le shell mongo a par défaut la reconnexion automatique activée. J'insère un document dans une collection nommée stuff, puis je trouve tous les documents de cette collection. J'ai alors réglé une minuterie pour trente minutes et ai essayé la même trouvaille encore. Cela a échoué, mais le shell s'est reconnecté automatiquement et lorsque j'ai immédiatement réessayé ma recherche, cela a fonctionné comme prévu.

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

Nous sommes là pour vous aider

Bien sûr, si vous avez des questions, n'hésitez pas à nous contacter à [email protected]. Nous sommes là pour vous aider.

27
jared

Quelques recommandations pour les personnes ayant encore ce problème:

  1. Assurez-vous que vous utilisez le dernier client mongodb pour node.js. J'ai remarqué des améliorations significatives dans ce domaine lors de la migration de la v1.2.x vers la v1.3.10 (la plus récente à ce jour).

  2. Vous pouvez transmettre un objet options à MongoClient.connect. Les options suivantes ont fonctionné pour moi lors de la connexion d'Azure à MongoLab:

    options = { db: {}, serveur: { auto_reconnect: true, socketOptions: {keepAlive: 1} }, replSet: {}, Mongos: {} };

    MongoClient.connect (dbUrl, options, fonction (err, dbConn) { // votre code });

  3. Voir cette autre réponse dans laquelle je décris comment gérer l'événement 'close' qui semble être plus fiable. https://stackoverflow.com/a/20690008/446681

6
Hector Correa

Activez l'option auto_reconnectServer comme ceci:

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

La connexion que vous ouvrez ici est en réalité un pool de 5 connexions (par défaut), vous avez donc raison de vous connecter et de le laisser ouvert. Mon hypothèse est que vous perdez de temps en temps la connectivité avec mongolab et que vos connexions meurent lorsque cela se produit. Espérons que l'activation de auto_reconnect résout ce problème.

1
JohnnyHK

L'augmentation des délais d'attente peut aider.

  • "socketTimeoutMS": Combien de temps un envoi ou une réception sur un socket peut prendre avant l'expiration du délai.
  • "wTimeoutMS": Il contrôle le nombre de millisecondes d'attente du serveur pour que le problème d'écriture soit satisfait.
  • "connectTimeoutMS": Combien de temps peut-il falloir pour qu'une connexion soit ouverte avant que le délai ne soit dépassé, en millisecondes.

    $ m = new MongoClient ("mongodb: //127.0.0.1: 27017", tableau .__ ("connect" => TRUE, "connectTimeoutMS" => 10, "socketTimeoutMS" => 10, "wTimeoutMS" => 10));

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

J'ai eu un problème similaire étant déconnecté de MongoDB périodiquement . Faire deux choses a résolu le problème:

  1. Assurez-vous que votre ordinateur ne dort jamais (cela mettra fin à votre connexion réseau).
  2. Contournez votre routeur/pare-feu (ou configurez-le correctement, ce que je n'ai pas encore compris comment faire).
0
Mike M. Lin