AWS Lambda(Node.js,v.8.10)和Mongoose:与数据库的MongoNetworkError连接超时

时间:2019-01-16 21:58:25

标签: node.js mongodb mongoose aws-lambda serverless

环境:

  • AWS Lambda(Node.js,第8.10版),waitForEmptyEventLoop === false
  • MongoDB(地图集)
  • 猫鼬

问题:有时(随机)出现下一个错误:

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 :(得分:0)

您需要一个“保持温暖”的脚本/功能,该脚本/功能可以通过频繁查询来保持连接的活动/热身。

此问题是由数据库连接超时或过期引起的,因为每次执行函数时Lambda都会启动一个新的计算实例。它不能使现有的连接保持温暖。

这是无服务器的已知问题,数据库连接持久性是间歇性的。

答案 1 :(得分:0)

只需增加socketTimeoutMS-对我来说就足够2000000,以保持lambda调用“温暖”容器之间的连接。 使用下一个配置(猫鼬):

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

另一个变体(smbd将此视为最佳实践)-为每个lambda调用创建/关闭连接。如果您知道lambda很少被调用,这是一个好主意