# [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  問題了。
        