爲了提高數據庫的IO速度,會使用連接池做處理,但是在高併發的情況下,一條連接完成任務後不釋放掉, 會導致鏈接池滿負載 ,後面的請求將無法處理,程序就會出現阻塞。
因此,當一條連接完成它的任務後,我們必須將它釋放掉。(基本代碼如下:)
var mysql = require('mysql');
var pool = mysql.createPool({
host:'127.0.0.1',
port:3306,
protocol:'mysql',
user:'root',
password:'123456',
database:'test_db',
connectionLimit:100 //最大連接數
})
pool.getConnection(function(err,conn){
if(err){
//do something
}
conn.query(sql,args,function(err,data){
if(err){
//do something
}else{
//return data or anything you want do!
}
conn.release(); //釋放連接
})
})
但是,程序還是會出現阻塞,於是又是各種查閱資源文檔。代碼並沒有任何錯誤。
爲了進一步測試,修改了connectionLimit的數值大小,改成200,繼續操作程序,沒有阻塞。可以確定是連接還佔用着資源
查看服務器MySQL當前連接
發現有一百多個處於sleep狀態的連接
當連接處於sleep狀態時會一直佔用資源。
mysql手冊中給出以下解釋:
1.客戶端程序在退出之前沒有關閉連接.[寫程序的疏忽,或者數據庫的db類庫沒有自動關閉每次的連接(例如沒有release(),當然,這裏我們已經使用了release())]
2.客戶端sleep的時間在wait_timeout或interactive_timeout規定的秒內沒有發出任何請求到服務器. [類似長連,類似於不完整的tcp ip協議構造,服務端一直認爲客戶端仍然存在(有可能客戶端已經斷掉了)]
3.客戶端程序在結束之前向服務器發送了請求還沒得到返回結果就結束掉了
解決方法以下兩種:
1、修改mysql配置文件,在[mysqld]下填加以下代碼
wait_timeout=10
修改完成後重啓服務,但是重啓服務往往不是件好事。因此有了第二種方法
2、通過mysql命令修改
set global wait_timeout = 10;
/**wait_timeout默認爲28800,試想一下,佔用這麼長時間能不出事嗎!**/
修改完成後再次操作程序,問題已解決
新猿一枚 ,若讀者發現文中有誤之處,還請提出。感謝!