1. 程式人生 > >nodejs中mysql斷線重連

nodejs中mysql斷線重連

調試 狀態 pan var 參考 ble prot nec clas

之前寫了個小程序Node News,用到了MySQL數據庫,在本地測試均沒神馬問題。放上服務器運行一段時間後,偶然發現打開頁面的時候頁面一直處於等待狀態,直到Nginx返回超時錯誤。於是上服務器檢查了遍,發現程序仍然在運行,且能正確記錄每次的請求,再修改代碼跟蹤調試,原來是在查詢數據庫的時候,回調一直沒有被執行,程序就掛在那裏了。

想了很久也想不明白為神馬mysql模塊沒有執行回調,最後突然想起來去看了下錯誤日誌,才發現有個“No reconnection after connection lost”錯誤沒有被捕捉到,原來是連接丟失了,上github上看了下文檔和issues,上面說到連接丟失後不會自動重新連接,會觸發error事件。我趕緊給程序添加了斷線後自動重連功能,現在已正常運行了10多天。

MySQL中有一個名叫wait_timeout的變量,表示操作超時時間,當連接超過一定時間沒有活動後,會自動關閉該連接,這個值默認為28800(即8小時)。

自動重連數據庫的代碼:

function handleError (err) {
  if (err) {
    // 如果是連接斷開,自動重新連接
    if (err.code === ‘PROTOCOL_CONNECTION_LOST‘) {
      connect();
    } else {
      console.error(err.stack || err);
    }
  }
}

// 連接數據庫
function connect () {
  db = mysql.createConnection(config);
  db.connect(handleError);
  db.on(‘error‘, handleError);
}

var db;
connect();

網上流傳的大多數使用mysql模塊的代碼,往往忽略了這個問題,一不小心就讓一撥又一撥的人往坑裏踩了。

有童鞋回復問使用pool又會怎樣,於是去看了下mysql模塊的源碼:目前可在npm中安裝到的最新版本為2.0.0-alpha7,使用mysql.createPool()來創建的pool沒辦法自動處理連接被關閉的問題,但是在github上的版本已經修復了(應該還沒發布到npm上),當觸發了connection的error事件時,會把該connection對象從連接池中移除。(源碼:https://github.com/felixge/node-mysql/blob/master/lib/Pool.js#L119 )

使用pool的代碼:

var mysql = require(‘mysql‘);
var pool  = mysql.createPool(config);

pool.getConnection(function(err, connection) {
  // Use the connection
  connection.query( ‘SELECT something FROM sometable‘, function(err, rows) {
    // And done with the connection.
    connection.end();

    // Don‘t use the connection here, it has been returned to the pool.
  });
});

參考: 《Nodejs使用mysql》 《No reconnection after connection lost》 《mysql自動斷開連接的問題處理方案》 《MySQL數據庫連接超時(wait_timeout)問題的處理》

nodejs中mysql斷線重連