# [Nodejs] 解決 MySQL Error: Connection lost. The server closed the connection 的方法
# 定時斷線若無跡可尋真的很令人頭大
最近在幫朋友使用 nodeJs 架測試用伺服器時發生一件令我困擾萬分的問題。
那就是,我的 nodeJs Server 所連接的 mysql 資料庫大約在幾個小時後就會自動斷線,使 nodeJs Server 拋出一個 PROTOCOL_CONNECTION_LOST
的 Exception。
MySQL Error: Connection lost. The server closed the connection
。
我一開始以為是自己的程式程式問題,千測萬測找不出原因來。之後在網路上查找,才知道原來是因為 MySQL 本身有一個機制: wait_time
。當超超過這個時間的時候便會 connection lost
. 這時,再去 request MySQL 時便會連接不上 MySQL。
解決方法網路上查到有兩種
# 第一種方法:在偵測到拋出 PROTOCOL_CONNECTION_LOST
時就重新執行連線。
在偵測到拋出 PROTOCOL_CONNECTION_LOST
時就重新執行連線。我們可以把這封裝成一個 module,在需要的地方使用。要注意的是,在使用 conn
時,不可以將其設為 global variable
,不然無法得到更新的 conn
。
var mysql = require('mysql'); | |
var mysql_config = { | |
host: '127.0.0.1', | |
user:'your user', | |
password:'your password', | |
database:'your database' | |
}; | |
function disconnect_handler() { | |
let conn = mysql.createConnection(mysql_config); | |
conn.connect(err => { | |
(err) && setTimeout('disconnect_handler()', 2000); | |
}); | |
conn.on('error', err => { | |
if (err.code === 'PROTOCOL_CONNECTION_LOST') { | |
//db error 重新連線 | |
disconnect_handler(); | |
} else { | |
throw err; | |
} | |
}); | |
exports.conn = conn; | |
} | |
exports.disconnect_handler = disconnect_handler; |
# 第二種方法:使用 Connection pool
使用 Connection pool。當需要 connection 時,從 connection pool 拿取連線即可。
程式碼大約如下:
var mysql = require("mysql"); | |
var pool = mysql.createPool({ | |
host: 'your host', | |
user:'your account', | |
password:'your password', | |
database:'your database', | |
connectionLimit : 10, // 可以自己設定 | |
}); | |
var query = function(sql, options, callback) { | |
console.log(sql, options, callback); | |
if (typeof options === "function") { | |
callback = options; | |
options = undefined; | |
} | |
pool.getConnection(function(err, conn){ | |
if (err) { | |
callback(err, null, null); | |
} else { | |
conn.query(sql, options, function(err, results, fields){ | |
// callback | |
callback(err, results, fields); | |
}); | |
// release connection。 | |
// 要注意的是,connection 的釋放需要在此 release,而不能在 callback 中 release | |
conn.release(); | |
} | |
}); | |
}; | |
module.exports = query; |
一樣將此封裝成一個 module,並且在想使用的地方使用。
我後來選擇了第二種方式,並且封裝成一個 middleware。大約類似如此方式使用:
app.use(function (req, res, next) {
req.query = mysqlPoolQuery;
next();
});
如此一來就順利解決了 mySQL 的 connection closed
問題了。