【问题标题】:Connection goes idle and disconnects Mongodb from AWS Lambda连接空闲并断开 Mongodb 与 AWS Lambda 的连接
【发布时间】:2020-11-30 00:39:05
【问题描述】:

MongoDB 空闲问题让我做噩梦。它无缘无故地失败,它不会触发断开事件或错误。它只是在 API 调用过程中断开连接。

我也尝试过阅读博客和旧问题并尝试了所有方法,但情况仍然没有任何帮助。

这是我的数据库连接代码:

function connect () {

return mongoose.connect(process.env.MONGO_DB_URI, {
    useNewUrlParser: true,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000,
    bufferMaxEntries: 0, // and MongoDB driver buffering
    bufferCommands: false, // Disable mongoose buffering
    ha: true, // Make sure the high availability checks are on
    haInterval: 10000 // Run every 10 seconds
  })
}

if (process.env.MONGO_DB_URI) {
  connect()
}

我还记录了数据库的几个事件。

db.on('connecting', () => {
  debug(`mongoose : connecting `)
})

db.on('connected', () => {
  debug(`mongoose : connected`)
})
db.on('open', () => {
  debug(`mongoose : open`)
})
db.on('disconnecting', () => {
  debug(`mongoose : disconnecting`)
})
db.on('disconnected', () => {
  debug(`mongoose : disconnected`)
})
db.on('close', () => {
  debug(`mongoose : close`)
})
db.on('reconnected', () => {
  debug(`mongoose : reconnected`)
})
db.on('error', (err) => {
  debug(`mongoose : error`, err)
})
db.on('all', () => {
  debug('mongoose: all')
})
db.on('fullsetup', () => {
  debug(`mongoose : fullsetup`)
})

在调用 API 之前,我还会检查来自中间件的数据库连接。

app.use(async (req, res, next) => {
  log.info('Ready State: ' + mongoose.connection.readyState, {
    action: 'App.ConnectionCheck'
  })
  if (mongoose.connection.readyState !== 1) {
    log.info('try to reconnect', {
      action: 'App.ConnectionCheck'
    })
    await connect()
    next()
  } else if (mongoose.connection && mongoose.connection.db) {
    await Promise.race([
      mongoose.connection.db.admin().ping(),
      new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error('Race condition failed'))
        }, 1000)
      })
    ]) 
    .then(async d => {
      log.info('ping successful: ', d)
      if (d.ok !== 1) {
        await connect()
      }
    })
    .catch(async e => {
      log.error('Ping Failed ', {
        error: e
      })
      await connect()
    })
    next()
  } else {
    next()
  }
})

但有时仍会打入电话,并进行第一次查询,但我没有收到回复,我的 API 超时。

这是我的日志的样子,请注意重新连接所需的时间。

2020-08-10 16:30:55.465 (+05:00)        34c5812c-5446-4c0f-bddf-c4ca8a0117cb    INFO    ----------------- BODY END ------------
2020-08-10 16:30:55.466 (+05:00)        34c5812c-5446-4c0f-bddf-c4ca8a0117cb    INFO    Mongoose: meetings.countDocuments({ appntId: '<APP_ID_HERE>', '$or': [ { deleted: true }, { createdAt: { '$gt': new Date("Mon, 10 Aug 2020 11:30:45 GMT") } {})
Mon, 10 Aug 2020 11:30:55 GMT timify:db-handle:index mongoose : disconnected
Mon, 10 Aug 2020 11:31:15 GMT timify:db-handle:index mongoose : connected
Mon, 10 Aug 2020 11:31:15 GMT timify:db-handle:index mongoose : reconnected
END RequestId: 34c5812c-5446-4c0f-bddf-c4ca8a0117cb
END RequestId: 34c5812c-5446-4c0f-bddf-c4ca8a0117cb
REPORT RequestId: 34c5812c-5446-4c0f-bddf-c4ca8a0117cb  Duration: 30030.13 ms   Billed Duration: 30000 ms       Memory Size: 10
Max Memory Used: 172 MB

版本

  • “猫鼬”:“^5.4.17”
  • “nodejs”:“12.x”
  • “mongodb-driver”:“3.1”

我看过另一个关于这个问题的帖子,但我的环境不同,这个问题是从 2016 年开始的。

【问题讨论】:

  • 这是 lambda 的哪一部分?全部?
  • 它是一个快速应用程序,用于托管在 lambda 上的 API
  • 找到任何解决方案了吗?如果 bufferCommands 设置为 True 会发生什么

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


【解决方案1】:

我在 AWS Lambda 上运行 Express 应用时遇到了类似的问题。

我得到的错误信息是:

MongooseError: Cannot call `users.find()` before initial connection is complete if `bufferCommands = false`. Make sure you `await mongoose.connect()` if you have `bufferCommands = false`.

我当前有效的连接设置是

mongoose
    .connect(mongoConnectionString, {
        useNewUrlParser: true ,
        useCreateIndex: true,
        useUnifiedTopology: true,
        keepAlive : true,
        bufferMaxEntries: 0 // and MongoDB driver buffering
    }
);

通过反复试验,我设法找到了连接错误

bufferCommands:假

命令和注释让它对我有用。

我通过mongoose documentation 找不到有关缓冲选项的任何原因,但您可以尝试通过以下方式全局关闭缓冲,

mongoose.set('bufferCommands', false);

希望此解决方案有所帮助。

编辑:将 bufferCommands 全局设置为 false,导致同样的错误。

【讨论】:

  • 你可以在我的设置中看到我已经关闭了它们
  • 是的,我已经看到了,将其设置为关闭是问题背后的原因。要么根本不使用该设置,要么将其注释掉。
  • 请注意 bufferMaxEntries 不存在于 mongoose 6。您可以在他们的 typedef 中确认这一点。
猜你喜欢
  • 1970-01-01
  • 2014-09-12
  • 2015-08-13
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 2020-02-27
相关资源
最近更新 更多