長連接和短連接


概念解釋:

長連接:

長時間保持客戶端與服務端的連接狀態。默認超時時間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; 
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM