ACTUALIZACIÓN: estoy usando la versión 2.1 en el controlador, contra 3.2
Tengo una aplicación de nodo que usa MongoDB. El problema que tengo es que si el servidor MongoDB se cae por algún motivo, la aplicación no se vuelve a conectar. Para hacerlo bien, basé mis pruebas en el código de este tutorial oficial .
var MongoClient = require('mongodb').MongoClient , f = require('util').format; MongoClient.connect('mongodb://localhost:27017/test', // Optional: uncomment if necessary // { db: { bufferMaxEntries: 3 } }, function(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({a:1}, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) });La idea es ejecutar este script y luego detener mongod y luego reiniciarlo. Así que, aquí vamos:
Detener MongoDb durante 10 segundos produce el resultado deseado: dejará de ejecutar las consultas durante esos 10 segundos y luego las ejecutará todas una vez que el servidor esté de vuelta.
Después de exactamente 30 segundos, empiezo a recibir:
{ [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' } insert { [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' }El problema es que a partir de ahora, cuando reinicio mongod, la conexión no se restablece .
¿Este problema tiene solución? Si es así, ¿sabes qué es? Una vez que mi aplicación comienza a vomitar "se destruyó la topología", la única forma de hacer que todo vuelva a funcionar es reiniciando toda la aplicación...
Hay 2 opciones de conexión que controlan cómo el controlador mongo nodejs se vuelve a conectar después de que falla la conexión
referencia en los documentos del controlador mongo
Lo que significa que mongo seguirá intentando conectarse 30 veces de forma predeterminada y esperará 1 segundo antes de cada reintento. Es por eso que comienzas a ver errores después de 30 segundos.
Debe modificar estos 2 parámetros en función de sus necesidades, como esta muestra.
var MongoClient = require('mongodb').MongoClient, f = require('util').format; MongoClient.connect('mongodb://localhost:27017/test', { // retry to connect for 60 times reconnectTries: 60, // wait 1 second before retrying reconnectInterval: 1000 }, function(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({ a: 1 }, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) });Esto intentará 60 veces en lugar de las 30 predeterminadas, lo que significa que comenzará a ver errores después de 60 segundos cuando deje de intentar volver a conectarse.
Nota al margen: si desea evitar que la aplicación/solicitud espere hasta el vencimiento del período de reconexión, debe pasar la opción bufferMaxEntries: 0 . El precio de esto es que las solicitudes también se abortan durante breves interrupciones de la red.
"mongodb": "3.1.3" Para ajustar la configuración de reconexión para conexiones preestablecidas, puede modificar las opciones reconnectTries / reconnectInterval ( valores predeterminados y documentación adicional aquí ).
Para la conexión inicial, el cliente mongo no se vuelve a conectar si encuentra un error (ver más abajo). Creo que debería , pero mientras tanto, he creado la siguiente solución usando la biblioteca promise-retry (que usa una estrategia de retroceso exponencial).
const promiseRetry = require('promise-retry') const MongoClient = require('mongodb').MongoClient const options = { useNewUrlParser: true, reconnectTries: 60, reconnectInterval: 1000, poolSize: 10, bufferMaxEntries: 0 } const promiseRetryOptions = { retries: options.reconnectTries, factor: 1.5, minTimeout: options.reconnectInterval, maxTimeout: 5000 } const connect = (url) => { return promiseRetry((retry, number) => { console.log(`MongoClient connecting to ${url} - retry number: ${number}`) return MongoClient.connect(url, options).catch(retry) }, promiseRetryOptions) } module.exports = { connect } Error de conexión inicial de Mongo: failed to connect to server [db:27017] on first connect
De forma predeterminada, el controlador Mongo intentará volver a conectarse 30 veces, una cada segundo. Después de eso, no intentará volver a conectarse.
Puede establecer la cantidad de reintentos en Number.MAX_VALUE para que siga reconectando "casi para siempre":
var connection = "mongodb://127.0.0.1:27017/db"; MongoClient.connect(connection, { server : { reconnectTries : Number.MAX_VALUE, autoReconnect : true } }, function (err, db) { });