Ne mongoDB ont reconnecter questions ou suis-je tout faux?
j'utilise nodejs et un mongoDB - et j'ai quelques problèmes de connexion.
Eh bien, en fait" wake " issues! Il se connecte parfaitement bien est super rapide et je suis heureux avec les résultats.
Mon problème: Si je n'utilise pas la connexion pendant un certain temps (je dis bien que, parce que le délai varie de 5+ minutes), il semble dans l'impasse. Je n'ai pas de déconnexion des événements déclenchés qu'il se bloque.
Finalement, J'obtiens une réponse comme Error: n'a pas réussi à se connecter à [ * .mongolab.com:*] - (*=valeurs masquées)
Un redémarrage rapide de l'application, et la connexion est à nouveau magnifique. Parfois, si Je ne redémarre pas l'application, je peux rafraîchir et il se reconnecte heureusement.
C'est pourquoi je pense qu'il est de "réveiller" les questions.
esquisse du code:
Je n'ai pas inclus le code - je ne pense pas que c'est nécessaire. Il fonctionne (en dehors de l'abandon de connexion)
les choses à noter: il n'y a qu'une "connexion" - Je ne la ferme jamais. Je n'ai jamais rouvrir.
j'utilise mongoose, 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 l'ouverture et la fermeture tout le temps - je crois que le consensus général est de faire comme je suis avec un emballage ouvert le lot. ??
j'ai essayé un testeur de connexion, qui continue de vérifier l'état de la connexion... même si cela semble dire que tout est ok, le problème se produit toujours.
j'ai eu ce numéro depuis le premier jour. J'ai toujours hébergé le MongoDB avec MongoLab. Le problème semble être pire sur localhost. Mais j'ai toujours le problème sur Azure et maintenant nodejit.su.
comme il arrive partout - il doit être moi, MongoDB, ou mongolab.
d'ailleurs j'ai avait une expérience similaire avec le pilote php aussi. (à confirmer c'est sur nodejs)
Ce serait formidable pour les aider, même si quelqu'un dit "c'est normal"
merci d'avance
Rob
6 réponses
mise à jour : notre article support pour ce sujet (essentiellement une copie de ce post) a été déplacé à notre dépannage de connexion doc .
on sait que le réseau Azure IaaS impose un délai d'inactivité d'environ treize minutes (déterminé empiriquement). Nous travaillons avec Azure pour voir si nous ne pouvons pas rendre les choses plus conviviales, mais en attendant d'autres ont eu du succès en configurant leur pilote options pour contourner le problème.
max connection idleep time
la solution la plus efficace que nous ayons trouvée en travaillant avec Azure et nos clients a été de régler le temps d'inactivité de la connexion max 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 réglé MongoDefaults.MaxConnectionIdleTime
à une minute et a réglé leurs problèmes.
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
le code d'application lui-même n'a pas changé, mais maintenant dans les coulisses le conducteur recycle agressivement les connexions au ralenti. Le résultat peut être vu dans les journaux du serveur aussi bien: beaucoup de roulement de connexion pendant les périodes inactives dans l'application.
il y a plus de détails sur cette approche dans le thread mongo-user connexe, SocketException using C# driver on azure .
Keepalive
vous pouvez également contourner le problème en rendant vos connexions moins inactives avec une sorte de keepalive . C'est un peu délicat à mettre en œuvre à moins que votre pilote ne le supporte hors de la boîte, habituellement en profitant de TCP Keepalive . Si vous avez besoin de rouler votre propre, assurez-vous de saisir chaque connexion de ralenti de la piscine toutes les deux minutes et de l'émission de quelques commande simple et bon marché, probablement un ping .
manipulation des déconnexions
Les déconnexionspeuvent se produire de temps en temps, même sans une configuration agressive du pare-feu. Avant d'entrer en production, vous voulez être sûr de les manipuler correctement.
tout d'Abord, assurez-vous d'activer la reconnexion automatique. La façon de le faire varie d'un conducteur à l'autre, mais lorsque le conducteur détecte qu'une opération a échoué parce que la connexion était mauvaise rebranchez indique au pilote d'essayer de se reconnecter.
mais cela ne résout pas complètement le problème. Vous avez encore la question de savoir quoi faire avec l'opération ratée qui a déclenché la reconnexion. La reconnexion automatique ne réessaie pas automatiquement les opérations ratées. Ce serait dangereux, surtout pour les Écritures. Donc habituellement une exception est lancée et l'application est demandée pour le gérer. Souvent, il est facile de retracer des lectures. Mais retrying écrit doit être soigneusement considérée.
Le shell mongo session ci-dessous illustre le problème. Le shell mongo par défaut a activé la reconnexion automatique. 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 de trente minutes et j'ai essayé la même chose. Il a échoué, mais le shell s'est automatiquement reconnecté et lorsque j'ai immédiatement retrouvé ma trouvaille, il 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 à support@mongolab.com. Nous sommes ici pour aider.
Merci pour tous les gars d'aide - j'ai réussi à résoudre ce problème à la fois sur localhost et déployé sur un serveur en direct.
Voici mon code de connexion qui fonctionne maintenant:
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);
});
je pense que le plus grand changement a été d'utiliser" createConnection "sur" connect " - Je l'avais déjà utilisé, mais peut-être que les options aident maintenant. Cet article a beaucoup aidé http://journal.michaelahlers.org/2012/12/building-with-nodejs-persistence.html
si je suis honnête, je ne suis pas trop sûr sur la raison pour laquelle j'ai ajouté ces options - comme mentionné par @jareed, j'ai également trouvé certaines personnes ayant du succès avec" MaxConnectionIdleTime " - mais autant que je peux voir le pilote javascript n'a pas cette option: c'était ma tentative d'essayer de répliquer le comportement.
So far So good - hope cette aide quelqu'un.
mise à jour: 18 avril 2013 note, Ceci est un deuxième application avec une configuration différente
maintenant je pensais que j'avais ceci résolu mais le problème est monté c'est tête moche à nouveau sur une autre application récemment - avec le même code de connexion. Confus!!!
cependant, la configuration était légèrement différente...
cette nouvelle application fonctionnait sur une fenêtre windows utilisant IISNode. Je ne voyais pas cela comme significatif au départ.
j'ai lu qu'il y avait peut - être des problèmes avec mongo sur Azure (@jareed), donc j'ai déplacé le DB vers AWS-mais le problème persistait.
donc j'ai commencé à jouer avec cet objet options à nouveau, lisant beaucoup sur elle. Je suis arrivé à cette conclusion:
options: {
server:{
auto_reconnect: true,
poolSize: 10,
socketOptions:{
keepAlive: 1
}
},
db: {
numberOfRetries: 10,
retryMiliSeconds: 1000
}
}
qui était un peu plus instruit que mon objet options d'origine je déclare. Toutefois - c'est toujours pas bon.
Maintenant, pour une raison quelconque, j'ai dû descendre de windows box (quelque chose à faire avec un module ne compilant pas) - il était plus facile de se déplacer que de passer une autre semaine à essayer de le faire fonctionner.
alors j'ai déménagé mon application à nodejitsu. faible et voici ma connexion est resté vivant! Woo!
.... qu'est-ce que cela signifie... je n'ai aucune idée! Ce que je sais, c'est est ces options semblent fonctionner sur Nodejitsu.... m'.
je crois que IISNode utilise une sorte de script" pour toujours " pour garder l'application vivant. Maintenant pour être juste l'application ne se bloque pas pour que cela se déclenche, mais je pense qu'il doit y avoir une sorte de "cycle app" qui est rafraîchie constamment - c'est comment il peut faire un déploiement continu (code ftp vers le haut, pas besoin de redémarrer app) - peut-être que c'est un facteur; mais je devine maintenant.
bien sûr, tout cela signifie que maintenant, ce n'est pas résolu. Il n'est toujours pas résolu. C'est juste résolu pour moi dans ma configuration.
Un couple de recommandations pour les personnes ayant encore cette question:
-
assurez-vous que vous utilisez le dernier client mongodb pour noeud.js. J'ai remarqué des améliorations significatives dans ce domaine lors de la migration de v1.2.x pour v1.3.10 (le dernier en date d'aujourd'hui)
-
vous pouvez passer un objet options au MongoClient.connecter. Les options suivantes ont fonctionné pour moi lors de la connexion D'Azure à MongoLab:
options = { DB: {}, serveur: { auto_reconnect: vrai, socketOptions: {keepAlive: 1} }, replSet: {}, mongos: {} };
MongoClient.connect (dbUrl, options, function (err, dbConn) { // votre code });
-
voir cette autre réponse dans laquelle je décris comment gérer l'événement de "fermeture" qui semble être plus fiable. https://stackoverflow.com/a/20690008/446681
activer le auto_reconnect
Server
option comme ceci:
var db = mongoose.connect(mongoConnect, {server: {auto_reconnect: true}});
la connexion que vous ouvrez ici est en fait un pool de 5 connexions (par défaut) donc vous avez raison de vous connecter et de la laisser ouverte. Je pense que vous perdez par intermittence la connectivité avec mongolab et vos connexions meurent quand cela se produit. Avec un peu de chance, activer auto_reconnect
résoudra cela.
l'Augmentation des délais d'attente peuvent aider.
- "socketTimeoutMS": combien de temps un envoi ou une réception sur une socket peut prendre avant d'expirer.
- "wTimeoutMS" : il contrôle combien de millisecondes le serveur attend l'écriture, à la préoccupation d'être satisfaits.
-
"connectTimeoutMS": combien de temps une connexion peut prendre pour être ouvert avant de chronométrer en millisecondes.
$M = nouveau 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);
j'ai eu un problème similaire étant déconnecté de MongoDB périodiquement . Faites deux choses fixé:
- assurez-vous que votre ordinateur ne dort jamais (qui va tuer votre connexion réseau).
- contournez votre routeur / pare-feu (ou configurez-le correctement, ce que je n'ai pas encore compris comment faire).