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

相關文章
相關標籤/搜索