nodejs中mysql斷線重連
之前寫了個小程序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斷線重連