web-dev-qa-db-fra.com

mongoError: la topologie a été détruite

J'ai un service REST intégré dans node.js avec Restify et Mongoose et un mongoDB avec une collection d'environ 30 000 documents de taille normale . Mon service de nœud est exécuté via pmx et pm2.

Hier, tout à coup, le noeud a commencé à chercher des erreurs avec le message "MongoError: la topologie a été détruite", rien de plus ... Je ne sais pas du tout ce que cela veut dire et ce qui aurait pu le déclencher. Il n’ya pas non plus grand-chose à trouver avec Google. Alors j'ai pensé que je demanderais ici.

Après le redémarrage du service de nœud aujourd'hui, les erreurs ont cessé d'arriver . J'ai également un de ceux-ci en production et cela me fait peur que cela puisse arriver à un moment donné à une partie assez cruciale de la configuration qui y est exécutée ...

J'utilise les versions suivantes des packages mentionnés:

  • mangouste: 4.0.3
  • restify: 3.0.3
  • noeud: 0.10.25
101
dreagan

Cela semble signifier que la connexion de votre serveur de noeud à votre instance MongoDB a été interrompue alors qu'il essayait d'écrire dessus.

Jetez un coup d’œil au code source Mongo qui génère cette erreur

Mongos.prototype.insert = function(ns, ops, options, callback) {
    if(typeof options == 'function') callback = options, options = {};
    if(this.s.state == DESTROYED) return callback(new MongoError(f('topology was destroyed')));
    // Topology is not connected, save the call in the provided store to be
    // Executed at some point when the handler deems it's reconnected
    if(!this.isConnected() && this.s.disconnectHandler != null) {
      callback = bindToCurrentDomain(callback);
      return this.s.disconnectHandler.add('insert', ns, ops, options, callback);
    }

    executeWriteOperation(this.s, 'insert', ns, ops, options, callback);
}

Cela ne semble pas être lié au problème Sails cité dans les commentaires, car aucune mise à niveau n'a été installée pour précipiter le crash ou le "correctif"

72
Jason Nichols

Je sais que la réponse de Jason a été acceptée, mais j'ai eu le même problème avec Mongoose et j'ai constaté que le service hébergeant ma base de données recommandait d'appliquer les paramètres suivants afin de maintenir en vie la connexion de Mongodb:

var options = {
  server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
  replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);

J'espère que cette réponse pourra aider d'autres personnes ayant des erreurs "La topologie a été détruite".

70
Adrien Joly

Cette erreur est due au fait que le pilote mongo a perdu la connexion pour une raison quelconque (le serveur était en panne par exemple).

Par défaut mongoose tentera de se reconnecter pendant 30 secondes, puis arrêtera de réessayer et lancera les erreurs pour toujours jusqu'à ce qu'elles soient redémarrées. 

Vous pouvez changer cela en modifiant ces 2 champs dans les options de connexion

mongoose.connect(uri, 
    { server: { 
        // sets how many times to try reconnecting
        reconnectTries: Number.MAX_VALUE,
        // sets the delay between every retry (milliseconds)
        reconnectInterval: 1000 
        } 
    }
);

documentation sur les options de connexion

56
Gaafar

Dans mon cas, cette erreur a été provoquée par une db.close(); dans une section "wait" dans "async"

MongoClient.connect(url, {poolSize: 10, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000}, function(err, db) {
    // Validate the connection to Mongo
    assert.equal(null, err);    
    // Query the SQL table 
    querySQL()
    .then(function (result) {
        console.log('Print results SQL');
        console.log(result);
        if(result.length > 0){

            processArray(db, result)
            .then(function (result) {
                console.log('Res');
                console.log(result);
            })
            .catch(function (err) {
                console.log('Err');
                console.log(err);
            })
        } else {
            console.log('Nothing to show in MySQL');
        }
    })
    .catch(function (err) {
        console.log(err);
    });
    db.close(); // <--------------------------------THIS LINE
});
10
Carlos Rodríguez

Juste un ajout mineur à la réponse de Gaafar, cela m'a donné un avertissement de dépréciation. Au lieu de sur l'objet serveur, comme ceci:

MongoClient.connect(MONGO_URL, {
    server: {
        reconnectTries: Number.MAX_VALUE,
        reconnectInterval: 1000
    }
});

Il peut aller sur l'objet de niveau supérieur. En gros, il suffit de le sortir de l'objet serveur et de le placer dans l'objet options comme ceci:

MongoClient.connect(MONGO_URL, {
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000
});
7
alucinare

"La topologie a été détruite" peut être causée par la déconnexion de la mangouste avant la création des index de documents mongos, par ce commentaire

Pour vous assurer que tous les modèles ont leurs index construits avant la déconnexion, vous pouvez:

await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));

await mongoose.disconnect();
4
golfadas

J'ai rencontré cela dans l'environnement kubernetes/minikube + nodejs + mongoose ... Le problème était que le service DNS était en place avec une sorte de latence. Vérifier que DNS est prêt a résolu mon problème.

const dns = require('dns');

var dnsTimer = setInterval(() => {
	dns.lookup('mongo-0.mongo', (err, address, family) => {
		if (err) {
			console.log('DNS LOOKUP ERR', err.code ? err.code : err);
		} else {
			console.log('DNS LOOKUP: %j family: IPv%s', address, family);
			clearTimeout(dnsTimer);
			mongoose.connect(mongoURL, db_options);
		}
	});
}, 3000);


var db = mongoose.connection;
var db_options = {
	autoReconnect:true,

	poolSize: 20,
	socketTimeoutMS: 480000,
	keepAlive: 300000,

	keepAliveInitialDelay : 300000,
	connectTimeoutMS: 30000,
	reconnectTries: Number.MAX_VALUE,
	reconnectInterval: 1000,
	useNewUrlParser: true
};

(les nombres dans db_options sont arbitraires sur stackoverflow et des sites similaires)

2
tkrizsa

J'ai aussi eu la même erreur. Enfin, j'ai trouvé une erreur sur mon code. J'utilise la répartition de charge pour deux serveurs nodejs, mais je viens de mettre à jour le code d'un serveur. 

Je change mon serveur mongod from standalone to replication, mais j'oublie de faire la mise à jour correspondante pour la chaîne de connexion, j'ai donc rencontré cette erreur.

chaîne de connexion autonome: mongodb://server-1:27017/mydb chaîne de connexion de réplication: mongodb://server-1:27017,server-2:27017,server-3:27017/mydb?replicaSet=myReplSet

détails ici : [mongo doc pour la chaîne de connexion]

2
lutaoact

J'ai eu cette erreur alors que je créais une nouvelle base de données sur ma communauté MongoDb Compass. Le problème était avec mon Mongod, il ne fonctionnait pas. Donc, comme solution, je devais exécuter la commande Mongod comme précédemment.

C:\Program Files\MongoDB\Server\3.6\bin>mongod

J'ai pu créer une base de données après avoir exécuté cette commande.

J'espère que ça aide.

1
Sibeesh Venu

Cela faisait quelque temps que je me débattais - comme vous pouvez le constater dans d’autres réponses, le problème peut être très différent.

Le moyen le plus simple de déterminer la cause est d’allumer loggingLevel: info dans les options.

1
orepor

Le commentaire de Sebastian sur la réponse d’Adrien nécessite plus d’attention, cela m’a aidé, mais c’est un commentaire qui peut être ignoré parfois alors voici une solution :

var options =  { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }
mongoose.connect(config.mongoConnectionString, options, (err) => {
    if(err) {
        console.error("Error while connecting", err);
    }
});
0
Black Mamba

Dans mon cas, cette erreur a été causée par une instance de serveur identique exécutant déjà l’arrière-plan. 

Ce qui est bizarre, c’est que lorsque j’ai démarré mon serveur sans préavis, il y en avait déjà un en cours d’exécution, la console ne montrait rien comme «quelque chose utilise le port xxx». Je pourrais même télécharger quelque chose sur le serveur. Donc, il m'a fallu beaucoup de temps pour localiser ce problème.

De plus, après avoir fermé toutes les applications imaginables, je ne pouvais toujours pas trouver le processus qui utilise ce port dans le moniteur d'activité de mon Mac. Je dois utiliser lsof pour tracer. Le coupable n’était pas surprenant - c’est un processus nodal. Cependant, avec le PID affiché sur le terminal, j'ai trouvé que le numéro de port sur le moniteur était différent de celui utilisé par mon serveur.

Dans l’ensemble, tuer tous les processus de nœuds peut résoudre ce problème directement.

0
AnLuoRidge

Vous devez redémarrer mongo pour résoudre l'erreur de topologie, puis modifier simplement certaines options de mangouste ou de mongoclient pour résoudre ce problème:

var mongoOptions = {
    useMongoClient: true,
    keepAlive: 1,
    connectTimeoutMS: 30000,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 5000,
    useNewUrlParser: true
}

mongoose.connect(mongoDevString,mongoOptions);
0
Ganesh sharma

Voici ce que j'ai fait, ça marche bien. Le problème avait disparu après avoir ajouté les options ci-dessous.

const dbUrl = "mongodb://localhost:27017/sampledb";
const options =  { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000, useNewUrlParser: true }
mongoose.connect(dbUrl,options, function(
  error
) {
  if (error) {
    console.log("mongoerror", error);
  } else {
    console.log("connected");
  }

});
0