Mongoose: Aucune nouvelle tentative n'est effectuée après « échec de la connexion lors de la première connexion »

Créé le 17 avr. 2017  ·  40Commentaires  ·  Source: Automattic/mongoose

Par défaut, mongoose renvoie une erreur si la première connexion échoue, ce qui fait planter le nœud.

Donc, pour reproduire ce bogue, vous aurez besoin du code suivant dans votre application, pour détecter l'erreur et éviter le plantage :

db.on('error', console.error.bind(console, 'connection error:'));

Maintenant, nous pouvons reproduire ce bug comme suit :

  1. Fermez votre MongoDB
  2. Démarrez votre application de nœud qui utilise la mangouste
  3. Votre application enregistrera : [MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017]]
  4. Redémarrez votre MongoDB
  5. Notez que mongoose ne se connecte pas maintenant à la MongoDB de travail. La seule façon de se reconnecter est de redémarrer votre application ou d'utiliser une solution de contournement manuelle .

Comportement attendu : étant donné que autoreconnect défini par défaut sur true, je m'attendrais à ce que mongoose établisse une connexion peu de temps après que MongoDB soit à nouveau accessible.

Remarque : si la première connexion réussit, mais que la connexion à MongoDB est perdue pendant l'exécution, la reconnexion automatique fonctionne correctement, comme prévu. Le problème est l'incohérence si MongoDB n'est pas disponible au démarrage de l'application.

(Si c'est le comportement souhaité et qu'il est recommandé aux développeurs de gérer cette situation en n'attrapant pas l'erreur et en laissant le nœud se bloquer, je peux l'accepter, mais cela vaut la peine de le préciser.)

noeud V4.4.1, [email protected] , [email protected] , [email protected]

docs

Commentaire le plus utile

Pour tous ceux qui souhaitent se reconnecter automatiquement lorsque la première connexion échoue, voici comment je le gère :

function createConnection (dbURL, options) {
    var db = mongoose.createConnection(dbURL, options);

    db.on('error', function (err) {
        // If first connect fails because mongod is down, try again later.
        // This is only needed for first connect, not for runtime reconnects.
        // See: https://github.com/Automattic/mongoose/issues/5169
        if (err.message && err.message.match(/failed to connect to server .* on first connect/)) {
            console.log(new Date(), String(err));

            // Wait for a bit, then try to connect again
            setTimeout(function () {
                console.log("Retrying first connect...");
                db.openUri(dbURL).catch(() => {});
                // Why the empty catch?
                // Well, errors thrown by db.open() will also be passed to .on('error'),
                // so we can handle them there, no need to log anything in the catch here.
                // But we still need this empty catch to avoid unhandled rejections.
            }, 20 * 1000);
        } else {
            // Some other error occurred.  Log it.
            console.error(new Date(), String(err));
        }
    });

    db.once('open', function () {
        console.log("Connection to db established.");
    });

    return db;
}

// Use it like
var db = createConnection('mongodb://...', options);
var User = db.model('User', userSchema);

Pour la mangouste < 4.11 utilisez db.open() au lieu de db.openUri()
Pour la mangouste 4.11.7, cette technique ne fonctionne pas.
Pour la mangouste 4.13.4 cela fonctionne à nouveau !


Edit 2019/09/02: Il existe également une solution plus courte en utilisant promiseRetry ici .

Tous les 40 commentaires

peut confirmer.
nœud 6, 7, mangouste (au moins 6 mois), mongo 3,2 - 3,4
vient avec celui-ci #4890

Je suppose que c'est un problème de mongodb-core . Il devrait tenter de se reconnecter même si le premier essai échoue, je pense, car je ne sais pas pourquoi cela serait différent des tentatives suivantes.

Pouvez-vous également y signaler ce problème ?

Voici un script de reproduction complet :

const mongoose = require('mongoose');
const co = require('co');
mongoose.Promise = global.Promise;
const GITHUB_ISSUE = `gh-5169`;


exec()
  .catch(error => {
    console.error(`Error: ${ error }\n${ error.stack }`);
  });


function exec() {
  return co(function*() {
    const db = mongoose.createConnection(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);
    db.on('error', (error) => {
      console.error(`in an error ${ error }\n${ error.stack }`);
    })
  });
}

Merci pour la repro. J'ai regardé dans mongodb-core. C'est le comportement voulu du conducteur :

Le pilote échouera lors de la première connexion s'il ne peut pas se connecter à l'hôte. Ceci est conçu pour assurer une défaillance rapide sur les hôtes inaccessibles. Le comportement de reconnexion ne démarre qu'une fois que le pilote a effectué la connexion initiale.

C'est à l'application de décider quoi faire. Ceci est conçu pour garantir que le pilote tombe en panne rapidement et ne reste pas là, vous faisant penser qu'il fonctionne réellement.

Je soupçonne donc que nous n'obtiendrons aucun comportement différent de la part du conducteur.

Je pense en fait que ce comportement est raisonnable pour un conducteur de bas niveau. Cela aidera les développeurs qui essaient accidentellement de se connecter au mauvais hôte ou au mauvais port.

Mais si nous voulons faire quelque chose de plus convivial pour les développeurs dans la mangouste, nous pourrions envisager :

  • Lorsque les options de reconnexion automatique sont activées, continuez d'essayer de vous reconnecter jusqu'à ce que le serveur Mongo puisse être contacté (en intégrant quelque chose comme la solution de contournement liée ci-dessus).
  • Connectez-vous lorsque la mangouste fait cela, donc dans le cas d'une connexion qui ne s'établit jamais, le développeur saura au moins où se trouve le problème.
    (Le journal pourrait être reporté, par exemple 30 secondes. En fait, au lieu d'une journalisation directe, je suppose que nous devrions émettre un événement consultatif error , mais toujours essayer de se reconnecter automatiquement.)

Si je me souviens bien, lorsque j'ai utilisé la solution de contournement et que je me suis finalement connecté après quelques tentatives infructueuses, les requêtes déjà mises en file d'attente par l'application ont été exécutées comme souhaité. (Mais cela vaut la peine de tester à nouveau.)

je pense que c'est une bonne idée en fait, je vais étiqueter cela une demande de fonctionnalité

Non, l'échec rapide lors de la connexion initiale est un comportement assez cohérent entre les pilotes MongoDB et il n'y a pas beaucoup d'avantages à le prendre en charge par mongoose.

Ce récent message du connecteur mongodb Strongloop Loopback peut être pertinent. Leur indicateur lazyConnect diffère la première connexion jusqu'à ce que le point de terminaison soit atteint. Si la première connexion échoue dans ce cas, les paramètres de perte de connexion par défaut prendront effet (il réessayera).

Mon intérêt est l'orchestration de conteneurs, où "l'ordre de démarrage des conteneurs" peut souvent être défini et attendu, mais pas "l'ordre de disponibilité du service". Un outil d'orchestration peut confirmer que le conteneur mongo est « actif » même si le service mongo n'est pas encore disponible.

Ainsi, si mon conteneur mongo prend 1s pour démarrer mais 5s pour que le service devienne disponible, et que mon conteneur d'applications prend 1s pour démarrer et 1s pour que le service soit disponible, le service d'application dépassera le service mongo, provoquant un premier échec de connexion comme décrit à l'origine .

La documentation de Docker Compose dit ceci :

Compose n'attendra pas qu'un conteneur soit "prêt" (quoi que cela signifie pour votre application particulière) - seulement jusqu'à ce qu'il soit en cours d'exécution. Il y a une bonne raison à cela.

Le problème d'attendre qu'une base de données (par exemple) soit prête n'est en réalité qu'un sous-ensemble d'un problème beaucoup plus vaste de systèmes distribués. En production, votre base de données peut devenir indisponible ou déplacer des hôtes à tout moment. Votre application doit être résiliente à ces types de défaillances.

Pour gérer cela, votre application doit tenter de rétablir une connexion à la base de données après un échec. Si l'application retente la connexion, elle devrait finalement pouvoir se connecter à la base de données.

La meilleure solution consiste à effectuer cette vérification dans le code de votre application, à la fois au démarrage et à chaque fois qu'une connexion est perdue pour une raison quelconque .

Il y a donc un écart certain ici dans le contexte de l'orchestration des conteneurs, mais ces deux positions semblent valables :

  1. Mongoose pourrait prendre en charge une option pour réessayer lors de la première connexion (peut-être la valeur par défaut est fausse avec une documentation de mise en garde), ou
  2. Mongoose pourrait confier au développeur la responsabilité d'écrire du code à réessayer si la première connexion échoue.

Bien sûr, il y a un écart, mais il vous incombe ensuite de décider de réessayer si la connexion initiale échoue. Tout ce que la mangouste vous dit, c'est qu'elle a échoué. Si vous prenez la décision douteuse d'utiliser docker compose en production (ou dans n'importe quel contexte d'ailleurs), c'est à vous de gérer les tentatives initiales d'échec de la connexion.

Position 2, c'est, alors.

Pour tous ceux qui souhaitent se reconnecter automatiquement lorsque la première connexion échoue, voici comment je le gère :

function createConnection (dbURL, options) {
    var db = mongoose.createConnection(dbURL, options);

    db.on('error', function (err) {
        // If first connect fails because mongod is down, try again later.
        // This is only needed for first connect, not for runtime reconnects.
        // See: https://github.com/Automattic/mongoose/issues/5169
        if (err.message && err.message.match(/failed to connect to server .* on first connect/)) {
            console.log(new Date(), String(err));

            // Wait for a bit, then try to connect again
            setTimeout(function () {
                console.log("Retrying first connect...");
                db.openUri(dbURL).catch(() => {});
                // Why the empty catch?
                // Well, errors thrown by db.open() will also be passed to .on('error'),
                // so we can handle them there, no need to log anything in the catch here.
                // But we still need this empty catch to avoid unhandled rejections.
            }, 20 * 1000);
        } else {
            // Some other error occurred.  Log it.
            console.error(new Date(), String(err));
        }
    });

    db.once('open', function () {
        console.log("Connection to db established.");
    });

    return db;
}

// Use it like
var db = createConnection('mongodb://...', options);
var User = db.model('User', userSchema);

Pour la mangouste < 4.11 utilisez db.open() au lieu de db.openUri()
Pour la mangouste 4.11.7, cette technique ne fonctionne pas.
Pour la mangouste 4.13.4 cela fonctionne à nouveau !


Edit 2019/09/02: Il existe également une solution plus courte en utilisant promiseRetry ici .

Salut @ vkarpov15 lorsque cela se produit, enregistrez également un rejet non géré de la bibliothèque mongodb-core.

MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017]
    at Pool.<anonymous> (/Users/development/okkralabs/sem-server/services/sem-access/node_modules/mongodb-core/lib/topologies/server.js:336:35)
    at emitOne (events.js:116:13)
    at Pool.emit (events.js:211:7)
    at Connection.<anonymous> (/Users/development/okkralabs/sem-server/services/sem-access/node_modules/mongodb-core/lib/connection/pool.js:280:12)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Connection.emit (events.js:214:7)
    at Socket.<anonymous> (/Users/development/okkralabs/sem-server/services/sem-access/node_modules/mongodb-core/lib/connection/connection.js:187:49)
    at Object.onceWrapper (events.js:315:30)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at emitErrorNT (internal/streams/destroy.js:64:8)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

C'est facile à reproduire, essayez de vous connecter avec un serveur MongoDb non disponible.

(node:2545) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017]
(node:2545) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Un moyen de le gérer ?

@jorgearanda quelle version de

@vkarpov15 Je pense que c'est un message pour @jorgecuesta ?

Oups, mon erreur. Silly github autocomplete, oui, c'était pour @jorgecuesta

Je vois exactement la même chose que @jorgecuesta , j'utilisais 4.11.5 et je vois la même chose avec 5.0.0-rc2. J'utilise createConnection car certains des modèles utilisent différentes bases de données sur la même instance mongo. Cela se produit lors du démarrage du serveur alors que mongo est en panne :

2018-01-07 13:05:23-05:00: [INFO] database - reusing existing connectioun for mongodb://localhost/eiss
2018-01-07 13:05:23-05:00: [INFO] database - initializing database connection to: mongodb://localhost/eiss
2018-01-07 13:05:23-05:00: [INFO] database - reusing existing connectioun for mongodb://localhost/eiss
2018-01-07 13:05:23-05:00: [ERROR] database - Mongoose connection error: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
Unhandled rejection MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
    at Pool.<anonymous> (/Users/bill/eiss4/js/node_modules/mongoose/node_modules/mongodb-core/lib/topologies/server.js:503:11)
    at emitOne (events.js:116:13)
    at Pool.emit (events.js:211:7)
    at Connection.<anonymous> (/Users/bill/eiss4/js/node_modules/mongoose/node_modules/mongodb-core/lib/connection/pool.js:326:12)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Connection.emit (events.js:214:7)
    at Socket.<anonymous> (/Users/bill/eiss4/js/node_modules/mongoose/node_modules/mongodb-core/lib/connection/connection.js:245:50)
    at Object.onceWrapper (events.js:315:30)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at emitErrorNT (internal/streams/destroy.js:64:8)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

Les modèles appellent une fonction de connexion avec le nom de la base de données qu'ils utilisent (ci-dessous). Tant que mongo est en cours d'exécution au démarrage du serveur, la montée et la descente de la base de données se reconnecte parfaitement (consignation des erreurs). Je viens de me rendre compte en lisant ce problème que le pilote gère la connexion initiale différemment, ce qui est assez ennuyeux. Je vais essayer la solution de contournement de @joeytwiddle , mais je soupçonne que cette exception non

const allConnections = {};

module.exports = function(dbName) {
  const url = 'http://localhost/' + dbName;
  let conn;
  log.info('initializing database connection to: ' + url);

  conn = allConnections[url];
  if (!conn) {
    log.info('creating new connection for ' + url);
    conn = mongoose.createConnection(url, {
      useMongoClient: true,
      autoReconnect: true,
      autoIndex: false,
      reconnectTries: Number.MAX_SAFE_INTEGER
    });    
    // Log database connection events
    conn.on('connected', () => log.info('Mongoose connection open to ' + url));
    conn.on('error', (err) =>  log.error('Mongoose connection error: ' + err));
    conn.on('disconnected', () => log.error('Mongoose connection disconnected'));  
    allConnections[url] = conn;
  }
  else {
    log.info('reusing existing connection for ' + url);
  }
  return conn;
}

@raythree dans le cas ci-dessus, ça devrait aller car vous avez .on('error') . Si vous souhaitez réessayer la connexion initiale en cas d'échec, je vous recommande d'utiliser simplement async/attendre pour cela cependant

let conn;
for (let i = 0; i < numRetries; ++i) {
  try {
    conn = await mongoose.createConnection(uri);
    break;
  } catch (error) {}
}

@vkarpov15 Désolé d'avoir tardé à vous répondre, nous utilisons 4.11.14 et 4.13.4

@jorgecuesta faire mongoose.connect(uri).catch(err => {})

@vkarpov15 connect() renvoie l'instance de connexion, n'est-ce pas ?

const connection = mongoose.connect(uri || undefined, {useMongoClient: true});
connection.once('error', (e) => {
  console.error(e, 'mongoose connection error.');
});
connection.once('connected', () => {
  console.log('mongoose connected');
});

Dans la version 5.0.0, nous l'avons modifié pour que mongoose.connect() renvoie une promesse de manière cohérente. Dans 4.x, il renvoie une instance de connexion mais avec .then() et .catch() donc vous pouvez l'utiliser avec await

Salut @joeytwiddle.

J'ai le même problème lors du déploiement sur Heroku.
MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]

Dans votre commentaire du 12 juillet 2017, vous avez proposé une solution de contournement. Je suis tout nouveau sur Mongoose/Node. Pouvez-vous me dire dans quel fichier votre fonction createConnection doit aller ?

J'exécute mangouste : ^5.0.10, nœud : v9.4.0
À votre santé

@juancarlucci Vous pouvez le mettre dans le fichier de votre

J'ai mis à jour le commentaire précédent pour montrer un exemple d'utilisation.

@joeytwiddle Merci pour l'exemple d'utilisation ! À votre santé.

Lorsque j'essaie de me connecter à mongo, une erreur s'affiche :

connection error: { MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connection 0 to localhost:27017 timed out]
    at Pool.<anonymous> (/home/wasd_xyz/Desktop/test/node_modules/mongodb-core/lib/topologies/server.js:505:11)
    at emitOne (events.js:116:13)
    at Pool.emit (events.js:211:7)
    at Connection.<anonymous> (/home/wasd_xyz/Desktop/test/node_modules/mongodb-core/lib/connection/pool.js:329:12)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Connection.emit (events.js:214:7)
    at Socket.<anonymous> (/home/wasd_xyz/Desktop/test/node_modules/mongodb-core/lib/connection/connection.js:256:10)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at Socket.emit (events.js:208:7)
    at Socket._onTimeout (net.js:420:8)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
  name: 'MongoNetworkError',
  message: 'failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connection 0 to localhost:27017 timed out]' }
(node:5453) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connection 0 to localhost:27017 timed out]
    at Pool.<anonymous> (/home/wasd_xyz/Desktop/test/node_modules/mongodb-core/lib/topologies/server.js:505:11)
    at emitOne (events.js:116:13)
    at Pool.emit (events.js:211:7)
    at Connection.<anonymous> (/home/wasd_xyz/Desktop/test/node_modules/mongodb-core/lib/connection/pool.js:329:12)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Connection.emit (events.js:214:7)
    at Socket.<anonymous> (/home/wasd_xyz/Desktop/test/node_modules/mongodb-core/lib/connection/connection.js:256:10)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at Socket.emit (events.js:208:7)
    at Socket._onTimeout (net.js:420:8)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
(node:5453) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:5453) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.


statut mongodb du service sudo

● mongodb.service - MongoDB Database
   Loaded: loaded (/etc/systemd/system/mongodb.service; enabled; vendor preset: 
   Active: active (running) since Sat 2018-06-23 17:13:28 IST; 13min ago
     Docs: https://docs.mongodb.org/manual
 Main PID: 4224 (mongod)
    Tasks: 24 (limit: 4915)
   CGroup: /system.slice/mongodb.service
           └─4224 /usr/bin/mongod --quiet --config /etc/mongod.conf

Jun 23 17:13:28 Inspiron5370 systemd[1]: Started MongoDB Database.


@pranshuchittora pouvez-vous montrer votre fichier de configuration MongoDB ? Assurez-vous que le port est 27017. Essayez également d'utiliser 127.0.0.1 au lieu de localhost

Essayez de vous connecter avec ip au lieu de localhost qui résoudra votre problème.

 let local = "mongodb://127.0.0.1:27017/XXX";
      mongoose.connect(
        local,
        { useNewUrlParser: true }
      );

Si la première tentative de connexion échoue, elle génère toujours une erreur.
Vous pouvez contourner cela en utilisant ci-dessous (par exemple, lorsque vous voulez vous assurer que la base de données est en cours d'exécution avant le démarrage de l'application/du script) :

[email protected]
@types/ [email protected]
@types/ [email protected]

async function waitForMongoDBStart(uri: string, timeoutMs: number) {

    return new Promise( async (resolve, reject) => {

        let endTime = Date.now() + timeoutMs;


        while (true) {

            let connectionError: Error;

            function errorHandler(err: Error) {
                connectionError = err;
            }
            mongoose.connection.once("error", errorHandler);

            await mongoose.connect(uri, {
                connectTimeoutMS: 5000, // This timeout applies only after connected & connection lost
                useNewUrlParser: true,
                useFindAndModify: false
            });

            // Time for error event propagation
            await wait(0);

            if ( ! connectionError) {
                mongoose.connection.removeListener("error", errorHandler);
                return resolve(); // All OK, connected
            }

            if (connectionError.name !== "MongoNetworkError") {
                return reject(`Unable to connect mongoDB. Details: ${connectionError}`);
            }

            if (Date.now() > endTime) {
                return reject(`Unable to connect mongoBD in ${timeoutMs} ms. Details: ${connectionError}`);
            }

        }

    });
}

@ vkarpov15 C'est un comportement très peu évident. Depuis https://mongoosejs.com/docs/connections.html :

connectTimeoutMS - How long the MongoDB driver will wait 
before failing its initial connection attempt. 
Once Mongoose has successfully connected, connectTimeoutMS is no longer relevant.

La documentation dit que cela devrait fonctionner avec la connexion initiale, mais ce n'est pas le cas. Avec l'erreur failed to connect to server , il échoue immédiatement.

S'il s'agit d'un comportement cohérent entre les pilotes MongoDB, ce serait bien d'avoir une option comme reconnectOnInitialFail qui sera false par défaut

Le comportement actuel est opposé à celui décrit par vkarpov15 -
connectImeoutMS n'a d'importance qu'après la première connexion (à la première connexion, il
est attendu que la base de données est démarrée et accepte la connexion, sinon immédiatement
l'erreur est levée)

sob., 22 gru 2018 o 13:03 Dmitry Kirilyuk [email protected]
napisał(a):

S'il s'agit d'un comportement cohérent entre les pilotes MongoDB, ce serait bien de
avoir une option comme reconnectOnInitialFail qui sera fausse par
défaut

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/Automattic/mongoose/issues/5169#issuecomment-449565468 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/ABY-TjgeI2UqVca050y5YY3zi6w7nMkfks5u7h-vgaJpZM4M-1ur
.

--
Wojciech Fiderek

Portable : +48 516 661 428

Si je me souviens bien, connectTimeoutMS est important lors de la connexion initiale en fonction des conditions du réseau et du système d'exploitation. Quand connectTimeoutMS est-il important après la connexion initiale ?

Dans mon cas, une erreur immédiate a été émise lorsque je n'ai pas pu me connecter au premier essai à l'instance mongod localhost sur Windows 10 et Alpine Linux (version inconnue). L'instance Mongod n'a pas encore démarré.
D'autres exemples que localhost ? N'importe qui?

@fider @Jokero J'ai creusé plus loin, et j'ai raison, connectTimeoutMS n'a d'importance que jusqu'à ce que vous ayez établi une première connexion, socketTimeoutMS prend le relais par la suite. Voici le code correspondant dans le pilote MongoDB :

connectTimeoutMS n'est pas toujours utile car vous obtiendrez généralement une erreur DNS ou une erreur de connexion refusée. Mais si, par exemple, vous ouvrez un serveur TCP qui écoute sur un port mais ne fait rien :

const net = require('net');

const server = net.createServer();

server.listen(27055);

Vous verrez que connectTimeoutMS en jeu :

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('debug', true);

const { Schema } = mongoose;

run().then(() => console.log('done')).catch(error => console.error(error.stack));

async function run() {
  await mongoose.connect('mongodb://localhost:27055', {
    useNewUrlParser: true,
    connectTimeoutMS: 1000,
    socketTimeoutMS: 25000
  });
} 
$ time node gh-5169.js 
MongoNetworkError: connection 0 to localhost:27055 timed out
    at Socket.<anonymous> (/mongoose/node_modules/mongodb-core/lib/connection/connection.js:259:7)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at Socket.emit (events.js:208:7)
    at Socket._onTimeout (net.js:407:8)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5)

real    0m2.293s
user    0m0.271s
sys 0m0.043s
$ 

Parfois, en raison de restrictions réseau, l'URL de MongoDB est bloquée, essayez de changer votre source réseau/Internet.

https://stackoverflow.com/questions/47958683/cannot-connect-to-mongodb-atlas-through-mongo-shell?answertab=active#tab -top

Lors d'une première connexion, (au moins) trois choses peuvent se produire :

  1. Il y a un mongodb et la connexion réussit, ouais !

  2. Le serveur répond "Connexion refusée", ce qui signifie qu'il n'y a pas de processus à l'écoute sur ce port, ou qu'il y a un pare-feu qui a _ activement rejeté_ la connexion. (Cela se produit généralement immédiatement, et je pense que c'est ce que Fider vivait.)

  3. Le serveur ne répond pas du tout, par exemple le pare-feu _lâche passivement_ les paquets ou il n'y a pas de serveur à cette adresse IP. (Dans ce cas, le connectTimeoutMS vkarpov est finalement déclenché.)

Le timeout n'est donc pas toujours utilisé. Il n'est utilisé que s'il n'y a pas de succès ou d'échec clair dans le temps imparti.

C'est courant dans le réseautage, et aussi lorsque l'on parle à une personne peu coopérative. Votre demande peut obtenir deux types de refus : « NON ! et .....

Merci pour la solide explication @joeytwiddle :+1:

Comment gérer ce comportement avec les connexions de jeu de réplicas utilisant mongodb+srv ? Lorsque mon jeu de réplicas est dans un scénario de redémarrage progressif (mise à jour de la base de données), je commence à recevoir des erreurs telles que connect ECONNREFUSED 34.238.xxx.xxx:27017 .

@esetnik utilisez-vous useUnifiedTopology: true et Mongoose 5.7.5 ? Nous avons identifié un problème #8209 qui pourrait être lié.

@vkarpov15 oui je le suis ! Merci pour le conseil. Je vais exécuter quelques tests après avoir désactivé la topologie unifiée et rendre compte de mes résultats.

Salut. J'ai exactement le même problème dans mon projet. avez-vous trouvé une solution pour cela ?!

@fdmxfarhan s'il vous plaît ouvrez un problème séparé et suivez le modèle de problème.

Cette page vous a été utile?
0 / 5 - 0 notes