AWS Lambda (Node.js, v. 8.10) и Mongoose: Превышено время ожидания подключения MongoNetworkError к БД - PullRequest
0 голосов
/ 17 января 2019

ENV:.

  • AWS Lambda (Node.js, v. 8.10), waitForEmptyEventLoop === false
  • MongoDB (Атлас)
  • Mongoose

Проблема: иногда (случайно) я получаю следующую ошибку:

MongoNetworkError: connection 6 to db_host:27017 timed out
  File "/opt/nodejs/node_modules/mongodb-core/lib/connection/connection.js", line 259, col 7, in TLSSocket.<anonymous>
    new MongoNetworkError(f('connection %s to %s:%s timed out', self.id, self.host, self.port)),
  File "events.js", line 313, col 30, in Object.onceWrapper
  File "events.js", line 106, col 13, in emitNone
  File "events.js", line 208, col 7, in TLSSocket.emit
  File "net.js", line 420, col 8, in TLSSocket.Socket._onTimeout
  File "timers.js", line 482, col 11, in ontimeout
  File "timers.js", line 317, col 5, in tryOnTimeout
  File "timers.js", line 277, col 5, in Timer.listOnTimeout

Код подключения БД:

const mongoose = require('mongoose');
const log = require('./log');

const options = {
  reconnectTries: 30,
  reconnectInterval: 500,
  poolSize: Number(process.env.DB_POOLSIZE) || 1,
  socketTimeoutMS: 30000,
  keepAlive: true,
  bufferCommands: false,
  bufferMaxEntries: 0,
};

let isConnected;

module.exports.connect = () => new Promise((resolve, reject) => {
  if (isConnected) {
    return resolve();
  }

  return mongoose.connect(process.env.DB_URI, options)
    .then((db) => {
      isConnected = db.connections[0].readyState;
      resolve();
    }).catch((error) => {
      log.error('DB:', error);
      reject(error);
    });
});

Я проверил - isConnected успешно кэшируется, соединение mongodb кэшируется в mongoose. Все должно быть в порядке, но иногда я получаю эту ошибку.

У кого-нибудь есть идеи, как мне решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Просто увеличьте socketTimeoutMS - мне достаточно 2000000, чтобы поддерживать связь между лямбдами при вызове «теплого» контейнера. Использовать следующий конфиг (мангуст):

 { reconnectTries: 30, reconnectInterval: 500, poolSize: 1, socketTimeoutMS: 2000000, keepAlive: true, }

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

0 голосов
/ 17 января 2019

Вам нужен сценарий / функция «поддерживать тепло», который будет поддерживать соединение «живым / теплым», выполняя запросы так часто.

Эта проблема вызвана тайм-аутом или истечением срока действия соединений с БД, поскольку Lambda запускает новый экземпляр вычислений при каждом выполнении функции. Не сохраняет существующее соединение теплым.

Это известная проблема, связанная с отсутствием сервера, когда постоянное соединение с БД прерывается.

...