Mongoose: Nenhuma nova tentativa é feita após "falha ao conectar na primeira conexão"

Criado em 17 abr. 2017  ·  40Comentários  ·  Fonte: Automattic/mongoose

Por padrão, o mongoose lança um erro se a primeira conexão falhar, o que causa falha no nó.

Portanto, para reproduzir esse bug, você precisará do seguinte código em seu aplicativo, para detectar o erro e evitar a falha:

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

Agora podemos reproduzir esse bug da seguinte maneira:

  1. Desligue seu MongoDB
  2. Inicie seu aplicativo de nó que usa mongoose
  3. Seu aplicativo irá registrar: [MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017]]
  4. Inicie seu MongoDB novamente
  5. Observe que o mongoose agora não se conecta ao MongoDB em funcionamento. A única maneira de se reconectar é reiniciar o aplicativo ou usar uma solução alternativa manual .

Comportamento esperado: como autoreconnect assume

Nota: Se a primeira conexão for bem-sucedida, mas a conexão com o MongoDB for perdida durante o tempo de execução, a reconexão automática funcionará bem, conforme o esperado. O problema é a inconsistência se o MongoDB não estiver disponível quando o aplicativo for inicializado.

(Se este for o comportamento desejado e os desenvolvedores forem recomendados a lidar com essa situação não detectando o erro e deixando o nó travar, então posso aceitar isso, mas vale a pena deixar isso claro.)

node v4.4.1, [email protected] , [email protected] , [email protected]

docs

Comentários muito úteis

Para quem deseja reconexão automática quando a primeira conexão falha, é assim que eu lido com isso:

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);

Para mangusto <4.11, use db.open() vez de db.openUri()
Para o mangusto 4.11.7, essa técnica não funciona.
Para o mangusto 4.13.4 está funcionando novamente!


Editar 02/09/2019: Também existe uma solução mais curta usando promiseRetry aqui .

Todos 40 comentários

pode confirmar.
nó 6, 7, mangusto (pelo menos 6 meses), mangusto 3,2 - 3,4
vem junto com este # 4890

estou supondo que este é um problema de mongodb-core . Ele deve tentar reconectar mesmo se a primeira tentativa falhar, eu acho, já que não tenho certeza por que isso seria diferente das tentativas subsequentes.

Você também pode relatar esse problema lá?

Aqui está um script de reprodução completo:

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 }`);
    })
  });
}

Obrigado pela reprodução. Eu olhei para o mongodb-core. É o comportamento pretendido do motorista :

O driver falhará na primeira conexão se não puder se conectar ao host. Isso ocorre por design para garantir falha rápida em hosts inacessíveis. O comportamento de reconexão só entra em ação depois que o driver realiza a conexão inicial.

Cabe ao aplicativo decidir o que fazer. Isso ocorre por design para garantir que o driver falhe rapidamente e não fique parado fazendo você pensar que está realmente funcionando.

Portanto, suspeito que não teremos nenhum comportamento diferente do motorista.

Na verdade, acho que esse comportamento é razoável para um driver de baixo nível. Isso ajudará os desenvolvedores que acidentalmente tentarem se conectar ao host errado ou à porta errada.

Mas se quisermos fazer algo mais amigável ao desenvolvedor no mangusto, podemos considerar:

  • Quando as opções de reconexão automática estão habilitadas, continue tentando reconectar até que o servidor Mongo possa ser contatado (criando algo como a solução alternativa vinculada acima).
  • Log quando o mangusto está fazendo isso, então, no caso de uma conexão que nunca se estabelece, o desenvolvedor saberá pelo menos onde está o problema.
    (O log pode ser adiado, por exemplo, 30 segundos. Na verdade, em vez de log direto, acho que deveríamos emitir um evento de aviso error , mas ainda assim tentar reconectar automaticamente.)

Se bem me lembro, quando usei a solução alternativa e finalmente me conectei após algumas tentativas malsucedidas, as consultas já enfileiradas pelo aplicativo foram executadas conforme desejado. (Mas vale a pena testar novamente.)

Acho que é uma ideia decente, na verdade, vou chamá-la de uma solicitação de recurso

Não, a falha rápida na conexão inicial é um comportamento bastante consistente entre os drivers do MongoDB e não há muitos benefícios no suporte do mongoose.

Esta postagem recente do conector mongodb Strongloop Loopback pode ser relevante. Seu sinalizador lazyConnect adia a primeira conexão até que o ponto de extremidade seja atingido. Se a primeira conexão falhar nesse caso, as configurações de perda de conexão padrão entrarão em vigor (haverá uma nova tentativa).

Meu interesse é a orquestração de contêineres, onde a "ordem de inicialização do contêiner" muitas vezes pode ser definida e esperada, mas a "ordem de disponibilidade do serviço" não. Uma ferramenta de orquestração pode confirmar que o contêiner mongo está "ativo", embora o serviço mongo ainda não esteja disponível.

Portanto, se meu contêiner mongo demorar 1s para iniciar, mas 5s para o serviço ficar disponível, e meu contêiner de aplicativo levar 1s para iniciar e 1s para o serviço estar disponível, o serviço de aplicativo ultrapassará o serviço mongo, causando uma primeira falha de conexão conforme descrito originalmente .

A documentação do Docker Compose tem o seguinte:

O Compose não esperará até que um contêiner esteja “pronto” (o que quer que isso signifique para seu aplicativo específico) - apenas até que ele esteja em execução. Há um bom motivo para isso.

O problema de esperar que um banco de dados (por exemplo) esteja pronto é, na verdade, apenas um subconjunto de um problema muito maior de sistemas distribuídos. Na produção, seu banco de dados pode ficar indisponível ou mover hosts a qualquer momento. Seu aplicativo precisa ser resiliente a esses tipos de falhas.

Para lidar com isso, seu aplicativo deve tentar restabelecer uma conexão com o banco de dados após uma falha. Se o aplicativo tentar a conexão novamente, ele deverá eventualmente ser capaz de se conectar ao banco de dados.

A melhor solução é realizar essa verificação no código do seu aplicativo, tanto na inicialização quanto sempre que uma conexão for perdida por qualquer motivo .

Portanto, há uma lacuna definida aqui no contexto da orquestração de contêineres, mas ambas as posturas parecem ser válidas:

  1. O Mongoose pode oferecer suporte a uma opção de tentar novamente na primeira conexão (talvez definido como falso por padrão com alguma documentação de advertência), ou
  2. O Mongoose pode atribuir ao desenvolvedor a responsabilidade de escrever o código para tentar novamente se a primeira conexão falhar.

Claro, há uma lacuna, mas cabe a você decidir se deve tentar novamente se a conexão inicial falhar. Tudo o que o mangusto diz é que ele falhou. Se você tomar a decisão questionável de usar docker compose na produção (ou em qualquer contexto para esse assunto), cabe a você lidar com as tentativas de falhas de conexão inicial.

Posição 2, então.

Para quem deseja reconexão automática quando a primeira conexão falha, é assim que eu lido com isso:

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);

Para mangusto <4.11, use db.open() vez de db.openUri()
Para o mangusto 4.11.7, essa técnica não funciona.
Para o mangusto 4.13.4 está funcionando novamente!


Editar 02/09/2019: Também existe uma solução mais curta usando promiseRetry aqui .

Olá @ vkarpov15, quando isso ocorrer, registre também uma rejeição não tratada da biblioteca 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)

Isso é fácil de reproduzir, tente conectar-se a um servidor MongoDb não disponível.

(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.

Alguma maneira de lidar com isso?

@jorgearanda que versão do mangusto você está usando e pode fornecer alguns exemplos de código?

@ vkarpov15 Acho que é uma mensagem para @jorgecuesta ?

Opa, erro meu. Github autocomplete idiota , sim, isso era para

Estou vendo exatamente a mesma coisa que @jorgecuesta , estava usando 4.11.5 e mas vejo o mesmo com 5.0.0-rc2. Estou usando createConnection porque alguns dos modelos estão usando bancos de dados diferentes na mesma instância do mongo. Acontece ao iniciar o servidor enquanto o mongo está inativo:

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)

Os modelos chamam uma função de conexão com o nome do banco de dados que estão usando (abaixo). Contanto que o mongo esteja em execução quando o servidor for iniciado, ativar e desativar o banco de dados reconecta-se perfeitamente (registrando os erros). Acabei de perceber ao ler este problema que o driver lida com a conexão inicial de forma diferente, o que é um tanto chato. Vou tentar a solução alternativa de @joeytwiddle , mas suspeito que essa exceção não tratada ainda ocorrerá.

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 no caso acima, você deve estar bem porque tem .on('error') . Se você quiser tentar a conexão inicial se ela falhar, recomendo que você use async / await para isso.

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

@ vkarpov15 Desculpe a demora em responder, estamos usando 4.11.14 e 4.13.4

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

@ vkarpov15 connect () retorna a instância de conexão, certo?

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');
});

No 5.0.0 nós mudamos isso para que mongoose.connect() retorne uma promessa de forma consistente. No 4.x, ele retorna uma instância de conexão, mas com .then() e .catch() para que você possa usá-lo com await

Olá @joeytwiddle.

Estou tendo o mesmo problema na implantação no Heroku.
MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]

Em seu comentário em 12 de julho de 2017, você deu uma solução alternativa. Sou totalmente novo no Mongoose / Node. Você pode me dizer em qual arquivo sua função createConnection deve ir?

Estou executando o mongoose: ^ 5.0.10, node: v9.4.0
Saúde

@juancarlucci Você pode colocá-lo em qualquer arquivo que desejar. Basta chamá-lo para obter uma instância do mangusto e usá-la para criar seus modelos.

Eu atualizei o comentário anterior para mostrar um exemplo de uso.

@joeytwiddle Obrigado pelo exemplo de uso! Saúde.

Quando tento me conectar ao mongo, ocorre um erro:

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.


sudo service mongodb status

● 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 você pode mostrar seu arquivo de configuração do MongoDB? Certifique-se de que a porta seja 27017. Além disso, tente usar 127.0.0.1 em vez de localhost

Tente conectar-se com ip em vez de localhost que resolverá seu problema.

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

Se a primeira tentativa de conexão falhar, sempre gerará erro.
Você pode ignorar isso usando a seguir (por exemplo, quando quiser garantir que o banco de dados esteja em execução antes de iniciar o aplicativo / 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 Este é um comportamento nada óbvio. Em 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.

A documentação diz que deveria funcionar com a conexão inicial, mas não funciona. Com o erro failed to connect to server ele falha imediatamente.

Se for um comportamento consistente entre os drivers do MongoDB, seria bom ter alguma opção como reconnectOnInitialFail que será false por padrão

O comportamento atual é oposto a este descrito por vkarpov15 -
connectImeoutMS importa apenas após a primeira conexão (na primeira conexão
espera-se que o banco de dados seja iniciado e aceite a conexão, caso contrário, imediatamente
erro é lançado)

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

Se for um comportamento consistente entre os drivers do MongoDB, seria bom
tem alguma opção como reconnectOnInitialFail que será falsa por
predefinição

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/Automattic/mongoose/issues/5169#issuecomment-449565468 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ABY-TjgeI2UqVca050y5YY3zi6w7nMkfks5u7h-vgaJpZM4M-1ur
.

-
Wojciech Fiderek

Celular: +48 516 661 428

Se bem me lembro, connectTimeoutMS importa na conexão inicial, dependendo das condições de rede e sistema operacional. Quando o connectTimeoutMS é importante após a conexão inicial?

No meu caso, ocorreu um erro imediato quando não consegui conectar na primeira tentativa de localhost mongod instance no Windows 10 e Alpine Linux (versão desconhecida). A instância do Mongod ainda não foi iniciada.
Outros exemplos além de localhost? Qualquer um?

@fider @Jokero Eu cavei mais fundo, e estou certo, connectTimeoutMS só importa até que você tenha feito uma conexão inicial, socketTimeoutMS assume depois. Aqui está o código relevante no driver MongoDB:

connectTimeoutMS nem sempre é útil porque você geralmente obterá um erro de DNS ou um erro de conexão recusada. Mas se você, digamos, abrir um servidor TCP que escuta em uma porta, mas não faz nada:

const net = require('net');

const server = net.createServer();

server.listen(27055);

Você verá que connectTimeoutMS entra em ação:

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
$ 

às vezes, devido a restrições de rede, os urls do MongoDB são bloqueados, tente alterar sua fonte de rede / internet.

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

Ao fazer uma conexão inicial, (pelo menos) três coisas podem acontecer:

  1. Há um mongodb e a conexão é bem-sucedida, yay!

  2. O servidor responde "Conexão recusada", o que significa que não há processo escutando nesta porta, ou há um firewall que _ rejeitou_ ativamente_ a conexão. (Isso geralmente acontece imediatamente, e acho que era isso que Fider estava experimentando.)

  3. O servidor não responde de forma alguma, por exemplo, o firewall _pagou passivamente_ os pacotes ou não há servidor naquele endereço IP. (Neste caso, connectTimeoutMS vkarpov é eventualmente acionado.)

Portanto, o tempo limite nem sempre é usado. Só é usado se não houver sucesso ou fracasso claro no tempo determinado.

Isso é comum em redes e também ao falar com uma pessoa que não coopera. Sua solicitação pode obter dois tipos de rejeição: "NÃO!" e .....

Obrigado pela explicação sólida @joeytwiddle : +1:

Como lidar com esse comportamento com conexões de conjunto de réplicas usando mongodb+srv ? Quando meu conjunto de réplicas está em um cenário de reinicialização contínua (atualização do banco de dados), começo a receber erros como connect ECONNREFUSED 34.238.xxx.xxx:27017 .

@esetnik, você está usando useUnifiedTopology: true e Mongoose 5.7.5? Identificamos um problema nº 8209 que pode estar relacionado.

@ vkarpov15 sim, estou! Obrigado pela dica. Vou executar alguns testes depois de desabilitar a topologia unificada e relatar minhas descobertas.

Oi. Eu tenho exatamente o mesmo problema em meu projeto. você encontrou alguma solução para isso ?!

@fdmxfarhan abra um problema separado e siga o modelo de problema.

Esta página foi útil?
0 / 5 - 0 avaliações