概念解釋:
長連接:
長時間保持客戶端與服務端的連接狀態。默認超時時間8小時
短連接:
數據傳輸完畢立即斷開,每次連接只完成一項業務的發送。
短連接的原理:
客戶端連接--創建socket認證連接--維護連接--數據傳輸--關閉連接 #連接-》數據傳輸-》關閉連接;
長連接的原理:
客戶端連接--創建socket認證連接--維護連接--數據傳輸--維護連接--數據傳輸.....-關閉連接 #連接-》數據傳輸-》保持連接-》數據傳輸-》保持連接-》…………-》關閉連接;
長短連接的例子
該使用長連接的情況下使用了短連接
某業務在審計時候發現連接數一直在直線上升:
mysql> select count(1) from db_monitor.accesslog; +----------+ | count(1) | +----------+ | 16117 | +----------+ 1 row in set (0.01 sec) mysql> select count(1) from db_monitor.accesslog; +----------+ | count(1) | +----------+ | 23768| +----------+ 1 row in set (0.01 sec) ...
截一段連接的審計圖給看看:

查看mysql的進程卻只有2-3個連接

但是每個連接幾乎不到1s鍾就關閉了,很典型的頻繁連接進行數據通信。這種業務就特別的消耗系統資源和mysql的資源。這種情況業務應該使用長連接來使用數據庫服務。 更改為長連接后,審計連接用戶數就馬上正常了,保持在一定的數值。
個人總結:
長連接主要用於在少數客戶端與服務端的頻繁通信,因為這時候如果用短連接頻繁通信常會發生Socket出錯,並且頻繁創建Socket連接也是對資源的浪費。
但是對於服務端來說,長連接也會耗費一定的資源,需要專門的線程(unix下可以用進程管理)來負責維護連接狀態
1、在頻繁的與數據庫服務通信,並且又非高並發的情況下,使用長連接更合適; 2、太多持久連接,大部分是sleep狀態的,或者系統是高並發的,使用短連接更合適。
+++++++++++++++++++++
首先,如果使用了長連接在閑置時間超過timeout值后,mysql server就會關閉此連接,而客戶端在執行查詢的時候就會得到一個類似於“MySQL server has gone away“這樣的錯誤。
在 使用mysql_real_connect連接數據庫之后,再使用mysql_options( &mysql, MYSQL_OPT_RECONNECT, … ) 來設置為自動重連。這樣當mysql連接丟失的時候,使用mysql_ping能夠自動重連數據庫。如果是在mysql 5.1.6之前,那么則應在每次執行完real_connect 之后執行mysql_options( &mysql, MYSQL_OPT_RECONNECT, … ) ,如果是mysql 5.1.6+,則在connect之前執行一次就夠了。
查看mysql連接數
mysqladmin -uroot -p processlist
當設置了MYSQL_OPT_RECONNECT為1時,超時后再查看processlist,則自動建立的連接不在列表中,但事實上連接確實建立並被使用了。
在MYSQL的默認設置中,長連接超時斷開后,后續在該連接上的查詢操作都將失敗。
解決辦法一:修改MYSQL服務器的配置參數
長連接的超時時間默認8小時,/etc/my.cnf中添加一行wait_timeout=超時時間 。
臨時配置方法:
用超級用戶登錄MYSQL,注意必須是超級用戶。然后輸入
目前默認的超時時間(8個小時單位是秒):
show global variables like 'wait_timeout'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | wait_timeout | 28800 | +---------------+-------+ 1 row in set (0.00 sec)
將超時時間設置成10個小時,可以輸入:
set global wait_timeout=36000; Query OK, 0 rows affected (0.00 sec)
這種方法設置的參數立即生效。但如果/etc/my.cnf中沒有配置,則重啟服務后,global變量會從/etc/my.cnf中讀取新的變量值。
下邊是一段示例代碼:
if(!mysql_real_connect(&logdb, my_hostname, my_user, my_password, my_dbname, my_port, my_sock, 0)){
ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", my_dbname, my_hostname);
use_mysql = 0;
} else {
char value = 1;
mysql_options(&logdb, MYSQL_OPT_RECONNECT, (char*)&value);
use_mysql = 1;
}
![]()
