Node.js 服务链接 MongoDB 处理最佳实践

关于如何处理 node.js 服务链接 MongoDB,我查阅了大量中英文资料,发现并无太适合我所指望的能力的方案,所以通过一番官方文档的研究,总结了如下的链接 MongoDB 的方法(使用目前 Node.js 平台最经常使用的 MongoDB ODM mongoose),斗胆称之为『最佳实践』,但愿可以抛砖引玉,获得你们更专业的解答。 话很少说,先上代码:node

const mongoose = require('mongoose')
const config = require('./config')


if (process.env.NODE_ENV === 'development') {
  mongoose.set('debug', true)    /* A */
}

mongoose.set('bufferCommands', false)  /* B */

function connectMongoDB(address) {
  try {
    mongoose.connect(address, { 
      useNewUrlParser: true,
      bufferMaxEntries: 0   /* B */
      autoReconnect: true   /* C, default is true, you can ignore it */
      poolSize: 5           /* D, default is 5, you can ignore it */
    })
    
    const db = mongoose.connection
    db.on('error', (error) => {
      console.log(`MongoDB connecting failed: ${error}`)
    })
    db.once('open', () => {
      console.log('MongoDB connecting succeeded')
    })
    return db
  } catch (error) {
    console.log(`MongoDB connecting failed: ${error}`)
  }
}

const mongoInstance = connectMongoDB(config.database.mongo)
module.exports = {
    mongoInstance
}
复制代码

这套链接方法可以知足如下需求,固然,这也是从个人服务须要知足的需求中总结而来的:mongodb

  1. 开发环境下可以打印详细的数据库操做信息
  2. 与数据库断开链接后,全部涉及到数据库读写操做的命令均会当即返回错误,而不会等待重连进而形成接口超时
  3. 服务启动并成功与数据库创建链接后,若是数据库出现问题形成链接中断,服务会自动尝试重连直到链接成功
  4. 无需手动处理链接数

咱们逐条来看每一个需求对应的配置:数据库

  1. 见注释 A,在开发环境中设置 'debug' 为 true,数据库将会把集合方法和参数打印到控制台。
  2. 见两处注释 B,这里贴一段 mongoose 文档中对 bufferMaxEntries 的解释:

bufferMaxEntries - The MongoDB driver also has its own buffering mechanism that kicks in when the driver is disconnected. Set this option to 0 and set bufferCommands to false on your schemas if you want your database operations to fail immediately when the driver is not connected, as opposed to waiting for reconnection.markdown

核心意思就是将 bufferMaxEntries 设为 0 同时将 bufferCommands 设为 false,可让驱动在未链接到数据库的时候,操做当即返回失败,而不是一直在等待重连。我的认为,这种方式相比一直等待数据库重连直到响应超时体验要更佳一点。多线程

  1. 见注释 C,这其实是 mongoose 的默认设置,其链接数据库时的 config 参数 autoReconnect 默认为 true,其含义见文档:

autoReconnect - The underlying MongoDB driver will automatically try to reconnect when it loses connection to MongoDB. Unless you are an extremely advanced user that wants to manage their own connection pool, do not set this option to false.less

若是非高级用户,就不要去改变这个参数了。mongoose

  1. 见注释 D。对于 MongoDB 链接池的问题,建议是不要去手动处理。mongoose 本身会维护一个默认最大数量为 5 的链接池,只有当你发现有一些慢查询可能阻塞快查询时才应该考虑增大 poolSize。固然,这个数字不能设置得过大,MongoDB 默认是一个链接启动一个线程来服务,链接太多线程数切换系统开销会很大。

固然,以上这套『最佳实践』还存在一个不足:若是服务初次启动后未能成功链接数据库(好比数据库此时处于宕机状态),则服务不会尝试重连数据库。解决方法也不是没有,就是比较鸡肋:在 mongoose 链接的 'error' 事件监听回调函数中尝试重连。可是须要设置最大重试次数,不然会发生内存泄露。比较鸡肋的缘由是,若是首次链接没有成功,短期内尝试重连几回貌似也无济于事。所以,使用这套链接方式务必要注意数据库保持可链接状态。或者读者们若是有更好的解决方案,也但愿能不吝赐教。函数

完。oop

本文首发于个人博客(点此查看),欢迎关注。ui

相关文章
相关标签/搜索