tcp長連線、短連線和心跳
原文:長連線、短連線和心跳(有圖有案例)_統木木的部落格-CSDN部落格
文章目錄
前言
在網路通訊過程中,主機與主機之前一般情況下是通過通過TCP協議進行連線
的,既然是連線,那麼就會有連線時間的長短,長時間的連線稱之為長連線,短時間的連線稱之為短連線,在長連線的過程中,由於是長時間連線,所以對於伺服器來說,需要去判斷連線進來的客戶端是不是還在連線的過程中,這裡就涉及到心跳的問題。就像人的心跳一樣,每跳動一次,就發出一個訊息,看看能不能得到迴應,如果能得到迴應,說明客戶端還在連線的過程中,如果得不到迴應,在一定的心跳次數下依然得不到迴應,就判斷長連線斷開了。
因此本文的主題就是:長連線
和心跳
、短連線
一 TCP連線
首先要明確一點,不管是長連線還是短連線都是在TCP連線的過程中發生的,也就是發生在網路的傳輸層上面。
簡單來說,當網路通訊時採用TCP協議時,在真正的讀寫操作之前,server與client之間必須建立一個連線,當讀寫操作完成後,雙方不再需要這個連線時它們可以釋放這個連線,連線的建立是需要三次握手的,而釋放則需要4次握手,所以說每個連線的建立都是需要資源消耗和時間消耗的。
二 長連線和心跳
1 概念
長連線是指在通訊過程中,兩臺主機可以多次傳輸資料,但是隻連線一次,做到連線的複用。一次資料傳輸後,不關閉連線,長期保持連通狀態。如果兩個應用程式之間有新的資料需要傳輸,則直接複用這個連線,無需再建立一個新的連線。示意圖如下:
2 優缺點
優點:
(1)省時間:在多次通訊中可以避免進行多次連線,從而節省了連線建立和關閉連線的開銷,並且從總體上來看,進行多次資料傳輸的總耗時更少,減少網路阻塞的影響。
(2)當發生錯誤時,可以在不關閉連線的情況下進行提示
(3)節約資源:減少CPU及記憶體的使用,因為不需要經常的建立及關閉連線。
缺點:
(1)連線數過多時,影響服務端的效能和併發數量。
(2)我們就需要擔心各種問題:比如**端對端連線的維護,連線的保活等。**需要花費額外的精力來保持這個連線一直是可用的,因為網路抖動、伺服器故障等都會導致這個連線不可用,甚至是由於防火牆的原因。
3 長連線的生命週期
正常情況下一直存在
4 使用場景
高頻請求的場景。
(1)資料庫的連線就是採用TCP長連線.
(2)RPC,遠端服務呼叫,在伺服器,一個服務程序頻繁呼叫另一個服務程序,可使用長連線,減少連線花費的時間。
5 心跳
將長連線和心跳一起介紹是因為心跳就是為長連線而設計的,既然是長連線,為了防止連線斷開或者說判斷連線是否依然存在,就需要有一種機制來進行判斷,這種機制就是心跳機制(HeartBeat)。
心跳:就像人的心跳一樣,人的心跳是用來續命的,通訊中的心跳是用來檢測一個系統是否存活或者網路鏈路是否通暢的一種方式,其一般做法是定時向被檢測系統傳送心跳包,被檢測系統收到心跳包進行回覆,收到回覆說明對方存活。心跳能夠給長連線提供保活功能,能夠檢測長連線是否正常(這裡所說的保活一方面可以理解為維持長連線,另一方面來說是一旦鏈路死了,不可用了,能夠儘快知道,然後做些其他的高可用措施,來保證系統的正常執行)。
心跳包機制:
心跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴伺服器,這個客戶端還活著。事實上這是為了保持長連線,至於這個包的內容,是沒有什麼特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。
在TCP的機制裡面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE
。系統預設是設定的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火牆這些斷線。而且邏輯層處理斷線可能也不是那麼好處理。一般,如果只是用於保活還是可以的。
心跳包一般來說都是在邏輯層傳送空的echo包來實現的。下一個定時器,在一定時間間隔下發送一個空包給客戶端,然後客戶端反饋一個同樣的空包回來,伺服器如果在一定時間內收不到客戶端傳送過來的反饋包,那就只有認定說掉線了。
其實,要判定掉線,只需要send或者recv一下,如果結果為零,則為掉線。但是,在長連線下,有可能很長一段時間都沒有資料往來。理論上說,這個連線是一直保持連線的,但是實際情況中,如果中間節點出現什麼故障是難以知道的。更要命的是,有的節點(防火牆)會自動把一定時間之內沒有資料互動的連線給斷掉。在這個時候,就需要我們的心跳包了,用於維持長連線保活。
在獲知了斷線之後,伺服器邏輯可能需要做一些事情,比如斷線後的資料清理呀,重新連線呀……當然,這個自然是要由邏輯層根據需求去做了。
總的來說,心跳包主要也就是用於長連線的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。
心跳檢測步驟:
1 客戶端每隔一個時間間隔發生一個探測包給伺服器
2 客戶端發包時啟動一個超時定時器
3 伺服器端接收到檢測包,應該回應一個包
4 如果客戶機收到伺服器的應答包,則說明伺服器正常,刪除超時定時器
5 如果客戶端的超時定時器超時,依然沒有收到應答包,則說明伺服器掛了
三 短連線
1 概念
短連線意味著每一次的資料傳輸都需要建立一個新的連線,用完再馬上關閉它。下次再傳輸資料的時候重新建立一個新的連線,如此反覆。示意圖如下:
2 優缺點
優點:
(1)管理簡單,不需要操心連線狀態的管理。
(2)由於每次使用的連線都是新建的,所以基本上只要能夠建立連線,資料就大概率能送達到對方。並且哪怕這次傳輸出現異常也不用擔心影響後續新的資料傳輸,因為屆時又是一個新的連線。
缺點:
(1)頻繁的連線就會浪費時間:每個連線都需要經過三次握手和四次握手的過程,耗時大大增加。
(2)致命的缺點:短時間內的大量連線導致埠數不夠用。socket 通訊過程包含通訊協議、目標地址、狀態等。實際當你在基於 socket 進行開發的時候,這些包含的具體資源主要就是這 5 個:源 IP、源埠、目的 IP、目的埠、協議,有個專業的叫法稱之為五元組”。在一臺計算機上只要這五元組的值不重複,那麼連線就可以被建立。然而一臺計算機最多隻能開啟 65535 個埠,如果現在兩個程序之間需要通訊,作為服務端的 IP 和埠必然是固定的,因此單個客戶端理論上最多隻能與服務端同時建立 65535 個 socket 連線。如果除去作業系統和其它程序所佔用的埠,實際還會更少。所以,一旦使用不當,在很短的時間內建立了大量連線,埠很容易被佔用完。這不但會導致自身無法正常工作,還會影響到同一臺計算機上的其它程序。我們在專案中大多數情況使用的是短連線的方式,因為這對我們程式設計來說可以少考慮很多問題,潛在的這些缺點可能是你沒有遇到或者意識到而已。
###3 使用場景
併發量大,請求頻率低的場景:通常瀏覽器訪問伺服器的時候就是短連線。對於服務端來說,長連線會耗費服務端的資源,而且使用者用瀏覽器訪問服務端相對而言不是很頻繁的如果有幾十萬,上百萬的連線,服務端的壓力會非常大,甚至會崩潰。所以對於併發量大,請求頻率低的,建議使用短連線。
四 長連線和短連線的選擇
1 長連線:高頻、服務端主動推送和有狀態
我想你肯定見過一些監控或者實時報價類系統,比如股票軟體,它需要在幾秒之內重新整理最新的價格。像這種場景中同時包含了需要運用長連線的三個主要因素:高頻、服務端主動推送和有狀態。
- 高頻的原因我想你根據前面的內容也明白了,因為頻次越高的話,使用短連線帶來的建立連線和關閉連線的總開銷越大。
- 而服務端主動推送也需要長連線的原因是,由於服務端往往是“中心化”的,一般都是 1 個服務端為多個客戶端提供服務。所以,如果使用短連線的方式,那麼在客戶端未主動連線到服務端的情況下,服務端並不知道需要往哪些客戶端去推送資料,這是原因之一。所以此時,長連線成為了一個很好的選擇。另外一個原因是,哪怕客戶端通過定時的短連線輪詢方式進行主動連線,除了增加了額外的建立連線和關閉連線的開銷外,還可能遇到通訊完成後結果資料並未發生變化,做了無用功。
- 成熟股票軟體的服務端,為了支撐更多的使用者以及做高可用,必然部署了多臺。但是這個業務場景,使用者無法容忍由於多個服務端之間資料同步的誤差導致他在客戶端看到的價格重新整理產生“回退”現象。所以,只能儘量保持一直連線在同一臺伺服器上,才能避免這個情況。這種場景被稱之為“有狀態”,也可以理解為是“序列”的,因為多次請求的前後需要保持“連續性”。
短連線使用場景:低頻、無狀態
短連線則更適用於諸如閱讀類軟體的場景中,例如,很多時候使用者點開一篇文章後需要花一些時間進行閱讀,這個時間有長有短,並且直到使用者下一次操作之前都沒有資料傳輸發生。這個場景中包含了運用短連線的兩個主要因素:低頻、無狀態。
- 因為低頻,所以更能容忍建立連線和關閉連線的開銷。
- 使用者的下一次點選往往跳轉到了其它文章,並且新開啟的與當前文章並不需要具有“連續性”,所以這種場景我們稱之為“無狀態”的。另外,理論上同一時刻開啟幾篇文章也不會存在什麼不妥。
五 參考部落格
參考部落格1:長連線和短連線詳細解析
原文連結:https://cloud.tencent.com/developer/article/1470024
參考部落格2:聊聊 TCP 長連線和心跳那些事
原文連結:http://blog.itpub.net/31556476/viewspace-2375225/
參考部落格3:長連線和心跳的那些事兒
原文連結:https://www.jianshu.com/p/c6af08f853d0
參考部落格4:長連線、短連線、心跳機制與斷線重連