Mongoose: После «не удалось подключиться при первом подключении» повторные попытки не выполняются.

Созданный на 17 апр. 2017  ·  40Комментарии  ·  Источник: Automattic/mongoose

По умолчанию мангуст выдает ошибку, если первое соединение не удается, что приводит к сбою узла.

Итак, чтобы воспроизвести эту ошибку, вам понадобится следующий код в вашем приложении, чтобы отловить ошибку и предотвратить сбой:

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

Теперь мы можем воспроизвести эту ошибку следующим образом:

  1. Выключите ваш MongoDB
  2. Запустите приложение узла, которое использует мангуст
  3. Ваше приложение будет регистрировать: [MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017]]
  4. Снова запустите MongoDB
  5. Обратите внимание, что mongoose теперь не подключается к работающей MongoDB. Единственный способ восстановить соединение - перезапустить приложение или использовать обходной путь вручную .

Ожидаемое поведение: поскольку для autoreconnect умолчанию установлено значение true, я ожидаю, что мангуст установит соединение вскоре после того, как MongoDB снова станет доступным.

Примечание. Если первое соединение прошло успешно, но соединение с MongoDB потеряно во время выполнения, автоматическое повторное соединение работает нормально, как и ожидалось. Проблема заключается в несогласованности, если MongoDB недоступен при запуске приложения.

(Если это желаемое поведение, и разработчикам рекомендуется справиться с этой ситуацией, не улавливая ошибку и не допуская сбоя узла, тогда я могу согласиться с этим, но стоит прояснить это.)

узел v4.4.1, [email protected] , [email protected] , [email protected]

Самый полезный комментарий

Для тех, кто хочет автоматическое переподключение при сбое первого подключения, я справляюсь с этим следующим образом:

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

Для мангуста <4.11 используйте db.open() вместо db.openUri()
Для мангуста 4.11.7 этот метод не работает.
Для мангуста 4.13.4 он снова работает!


Изменить 2019/09/02: здесь также есть более короткое решение с использованием promiseRetry .

Все 40 Комментарий

могу подтвердить.
узел 6, 7, мангуст (минимум 6 месяцев), монго 3,2 - 3,4
идет вместе с этим # 4890

Я предполагаю, что это проблема mongodb-core . Я думаю, он должен попытаться повторно подключиться, даже если первая попытка не удалась, поскольку я не уверен, почему это будет отличаться от последующих попыток.

Можете ли вы также сообщить об этой проблеме там?

Вот полный сценарий воспроизведения:

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

Спасибо за репродукцию. Я заглянул в mongodb-core. Это предполагаемое поведение водителя :

Драйвер не сможет подключиться при первом подключении, если он не сможет подключиться к хосту. Это сделано для того, чтобы обеспечить быстрый сбой на недоступных хостах. Поведение повторного подключения срабатывает только после того, как драйвер выполнил первоначальное подключение.

Приложение решает, что делать. Это сделано специально для того, чтобы драйвер быстро выходил из строя и не заставлял вас думать, что он действительно работает.

Так что я подозреваю, что мы не увидим другого поведения от водителя.

Я действительно считаю, что такое поведение разумно для водителя низкого уровня. Это поможет разработчикам, которые случайно попытаются подключиться не к тому хосту или к неправильному порту.

Но если мы хотим сделать что-то более удобное для разработчиков в мангусте, мы могли бы подумать:

  • Когда включены параметры автоматического переподключения, продолжайте попытки переподключиться до тех пор, пока с сервером Mongo не удастся связаться (путем создания чего-то вроде обходного пути, указанного выше).
  • Регистрируйте, когда мангуст делает это, чтобы в случае соединения, которое никогда не устанавливается, разработчик, по крайней мере, знал, в чем проблема.
    (Запись журнала может быть отложена, например, на 30 секунд. На самом деле, вместо прямого ведения журнала, я думаю, мы должны выдать предупреждающее событие error , но все же попытаться восстановить соединение автоматически.)

Если я правильно помню, когда я использовал обходной путь и, наконец, подключился после нескольких неудачных попыток, запросы, уже поставленные приложением в очередь, выполнялись должным образом. (Но это стоит проверить еще раз.)

На самом деле, я думаю, что это неплохая идея, я обозначу это как запрос функции

Нет, быстрый сбой при начальном подключении - это довольно последовательное поведение для драйверов MongoDB, и поддержка mongoose не особо выгодна.

Этот недавний пост из коннектора Strongloop Loopback mongodb может быть актуальным. Их флаг lazyConnect откладывает первое соединение до тех пор, пока не будет достигнута конечная точка. Если в этом случае первое соединение не удалось , вступят в силу умолчанию (будет выполнено повторное

Меня интересует оркестровка контейнеров, где часто можно установить и ожидать «порядок запуска контейнера», а «порядок доступности службы» - нет. Инструмент оркестровки может подтвердить, что контейнер mongo «работает», даже если сервис mongo еще недоступен.

Итак, если моему контейнеру mongo требуется 1 с для запуска, но 5 с для того, чтобы служба стала доступной, а моему контейнеру приложения требуется 1 с для запуска и 1 с для доступности службы, служба приложения опередит службу mongo, что вызовет сбой первого подключения. как первоначально описано .

В документации Docker Compose сказано следующее:

Compose не будет ждать, пока контейнер будет «готов» (что бы это ни значило для вашего конкретного приложения) - только до тех пор, пока он не запустится. Для этого есть веская причина.

Проблема ожидания готовности базы данных (например) на самом деле является лишь подмножеством гораздо более крупной проблемы распределенных систем. В производственной среде ваша база данных может стать недоступной или переместить хосты в любое время. Ваше приложение должно быть устойчивым к сбоям такого типа.

Чтобы справиться с этим, ваше приложение должно попытаться восстановить соединение с базой данных после сбоя. Если приложение попытается установить соединение, оно в конечном итоге сможет подключиться к базе данных.

Лучшее решение - выполнить эту проверку в коде приложения как при запуске, так и при потере соединения по какой-либо причине .

Таким образом, здесь есть определенный пробел в контексте оркестровки контейнеров, но обе эти позиции кажутся допустимыми:

  1. Mongoose может поддерживать возможность повторной попытки при первом подключении (возможно, по умолчанию установлено значение false с некоторой предупреждающей документацией) или
  2. Mongoose может возложить на разработчика ответственность за написание кода для повторной попытки в случае сбоя первого подключения.

Конечно, есть пробел, но тогда вы должны решить, следует ли повторить попытку, если начальное соединение не удалось. Все, что вам говорит мангуст, - это то, что он потерпел неудачу. Если вы примете сомнительное решение использовать docker compose в производственной среде (или в любом другом контексте, если на то пошло), вам решать, как обрабатывать повторные попытки первоначального сбоя подключения.

Итак, позиция 2.

Для тех, кто хочет автоматическое переподключение при сбое первого подключения, я справляюсь с этим следующим образом:

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

Для мангуста <4.11 используйте db.open() вместо db.openUri()
Для мангуста 4.11.7 этот метод не работает.
Для мангуста 4.13.4 он снова работает!


Изменить 2019/09/02: здесь также есть более короткое решение с использованием promiseRetry .

Привет @ vkarpov15, когда это происходит, также регистрирует необработанное отклонение из библиотеки 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)

Это легко воспроизвести, попробуйте подключиться к недоступному серверу MongoDb.

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

Как с этим справиться?

@jorgearanda, какую версию mongoose вы используете и можете ли вы предоставить образцы кода?

@ vkarpov15 Думаю, это сообщение для @jorgecuesta ?

Woops, моя ошибка. Глупое автозаполнение github, да, это было для @jorgecuesta

Я вижу то же самое, что и @jorgecuesta , я использовал 4.11.5, но вижу то же самое с 5.0.0-rc2. Я использую createConnection, поскольку некоторые модели используют разные базы данных в одном экземпляре mongo. Это происходит при запуске сервера, когда mongo не работает:

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)

Модели вызывают функцию соединения с именем базы данных, которую они используют (ниже). Пока mongo работает, когда сервер запускается, при поднятии и остановке базы данных происходит повторное подключение (регистрация ошибок). Я только что понял, читая этот выпуск, что драйвер по-другому обрабатывает начальное соединение, что немного раздражает. Я собираюсь попробовать обходной путь

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 в приведенном выше случае все должно быть в порядке, потому что у вас есть .on('error') . Если вы хотите повторить первоначальное соединение в случае сбоя, я бы рекомендовал вам просто использовать для этого async / await.

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

@ vkarpov15 Извините за задержку с ответом, мы используем 4.11.14 и 4.13.4

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

@ vkarpov15 connect () возвращает экземпляр соединения, верно?

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

В 5.0.0 мы изменили его так, чтобы mongoose.connect() возвращал обещание. В 4.x он возвращает экземпляр соединения, но с .then() и .catch() поэтому вы можете использовать его с await

Привет @joeytwiddle.

У меня такая же проблема при развертывании на Heroku.
MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]

В своем комментарии от 12 июля 2017 г. вы дали обходной путь / решение. Я новичок в Mongoose / Node. Можете ли вы сказать мне, в каком файле должна находиться ваша функция createConnection?

Я запускаю мангуст: ^ 5.0.10, узел: v9.4.0
Ваше здоровье

@juancarlucci Вы можете поместить его в любой файл, который вам нравится. Просто вызовите его, чтобы получить экземпляр мангуста и использовать его для создания своих моделей.

Я обновил предыдущий комментарий, чтобы показать пример использования.

@joeytwiddle Спасибо за пример использования! Ваше здоровье.

Когда я пытаюсь подключиться к mongo, выдает ошибку:

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 mongodb

● 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, можете ли вы показать свой файл конфигурации MongoDB? Убедитесь, что это порт 27017. Также попробуйте использовать 127.0.0.1 вместо localhost.

Попробуйте подключиться к ip вместо localhost, что решит вашу проблему.

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

Если первая попытка подключения не удалась, всегда возникает ошибка.
Вы можете обойти это, используя ниже (например, если хотите убедиться, что БД работает до запуска приложения / скрипта):

[email protected]
@ типы / [email protected]
@ типы / [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 Это очень неочевидное поведение. С 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.

В документации сказано, что он должен работать при первоначальном подключении, но это не так. С ошибкой failed to connect to server сразу же выходит из строя.

Если это согласованное поведение для драйверов MongoDB, было бы неплохо иметь какой-то параметр, например reconnectOnInitialFail который по умолчанию будет false

Текущее поведение противоположно описанному vkarpov15 -
connectImeoutMS имеет значение только после первого подключения (при первом подключении он
ожидается, что БД запущена и принимает соединение, в противном случае immedia
выдается ошибка)

соб., 22 гр 2018 в 13:03 Дмитрий Кирилюк [email protected]
написал (а):

Если это последовательное поведение драйверов MongoDB, было бы неплохо
есть такая опция, как reconnectOnInitialFail, которая будет ложной на
дефолт

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/Automattic/mongoose/issues/5169#issuecomment-449565468 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/ABY-TjgeI2UqVca050y5YY3zi6w7nMkfks5u7h-vgaJpZM4M-1ur
.

-
Войцех Фидерек

Мобильный: +48 516 661428

Если я правильно помню, connectTimeoutMS имеет значение при начальном подключении в зависимости от условий сети и ОС. Когда имеет значение connectTimeoutMS после первоначального подключения?

В моем случае сразу же возникла ошибка, когда я не смог подключиться с первой попытки к экземпляру localhost mongod в Windows 10 и Alpine Linux (версия неизвестна). Экземпляр Mongod просто еще не запущен.
Другие примеры, кроме localhost? Кто угодно?

@fider @Jokero Я connectTimeoutMS имеет значение только до тех пор, пока вы не установили начальное соединение, socketTimeoutMS вступает во владение позже. Вот соответствующий код в драйвере MongoDB:

connectTimeoutMS не всегда полезен, потому что обычно вы получаете ошибку DNS или ошибку отказа в соединении. Но если вы, скажем, откроете TCP-сервер, который прослушивает порт, но на самом деле ничего не делает:

const net = require('net');

const server = net.createServer();

server.listen(27055);

Вы увидите, что connectTimeoutMS :

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
$ 

иногда из-за сетевых ограничений URL-адрес MongoDB блокируется, попробуйте изменить свой сетевой / интернет-источник.

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

При первоначальном подключении могут произойти (как минимум) три вещи:

  1. Есть mongodb и соединение установлено, ура!

  2. Сервер отвечает: «В соединении отказано», что означает, что на этом порте не прослушивается процесс, или есть брандмауэр, который _активно отклонил_ соединение. (Обычно это происходит сразу, и я думаю, именно это и испытал фидер.)

  3. Сервер вообще не отвечает, например, брандмауэр _пассивно сбросил_ пакеты или на этом IP-адресе нет сервера. (В этом случае в конечном итоге срабатывает connectTimeoutMS Вкарпова.)

Так что тайм-аут используется не всегда. Он используется только в том случае, если в данный момент времени нет явного успеха или неудачи.

Это обычное явление в сети, а также при разговоре с человеком, отказывающимся сотрудничать. Ваш запрос может получить два типа отклонения: «НЕТ!» а также .....

Спасибо за подробное объяснение

Как следует обрабатывать такое поведение при подключении к набору реплик с использованием mongodb+srv ? Когда мой набор реплик находится в сценарии последовательного перезапуска (обновление базы данных), я начинаю получать такие ошибки, как connect ECONNREFUSED 34.238.xxx.xxx:27017 .

@esetnik , вы используете useUnifiedTopology: true и Mongoose 5.7.5? Мы обнаружили проблему № 8209, которая могла быть связана с этим.

@ vkarpov15 да я! Спасибо за совет. Я проведу несколько тестов после отключения единой топологии и сообщу о своих выводах.

Привет. У меня точно такая же проблема в моем проекте. Вы нашли какое-нибудь решение ?!

@fdmxfarhan, пожалуйста, откройте отдельный выпуск и следуйте шаблону

Была ли эта страница полезной?
0 / 5 - 0 рейтинги