JAVA之長連線、短連線和心跳包

lvxiangan發表於2018-10-23

短連線:

client向server發起連線,server接到請求,雙方建立連線,client向server傳送訊息,server回應client,一次讀寫完成雙方都可以發起close請求

  • 優點:短連線對於伺服器來說較為簡單,存在的連線都是有用的連線,不需要額外的控制。
  • 缺點:如果客戶端連線頻繁,會在tcp的建立和關閉上浪費時間。


長連線:

client向server發起連線,server接到請求,雙方建立連線,client向server傳送訊息,server回應client,一次讀寫完成,連線不關閉,後續讀寫操作,長時間操作之後client發起關閉請求。

  • 優點:長連線可以省去較多的tcp建立/關閉的操作,減少浪費,節省時間,對於頻繁請求資源的客戶,較適用於長連線
  • 缺點:client和server如果長時間不關閉的話,會存在一個問題,隨著客戶的越來越多,server早晚會有扛不住的一天,這時需要採取一些策略,如關閉一些長時間不讀寫操作的連線,這樣可以避免一些惡意連線導致server端服務受損,如果條件再允許,就可以以客戶端為顆粒度,限制每個客戶端的最大連線數

 

心跳包

很多應用層協議都有HeartBeat機制,通常是客戶端每隔一小段時間向伺服器傳送一個資料包,通知伺服器自己仍然線上,並傳輸一些可能必要的資料。使用心跳包的典型協議是IM,比如QQ/MSN/飛信等協議。

心跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴伺服器,這個客戶端還活著。事實上這是為了保持長連線,至於這個包的內容,是沒有什麼特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。

在TCP的機制裡面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統預設是設定的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火牆這些斷線。而且邏輯層處理斷線可能也不是那麼好處理。一般,如果只是用於保活還是可以的。

心跳包一般來說都是在邏輯層傳送空的echo包來實現的。下一個定時器,在一定時間間隔下傳送一個空包給客戶端,然後客戶端反饋一個同樣的空包回來,伺服器如果在一定時間內收不到客戶端傳送過來的反饋包,那就只有認定說掉線了。

其實,要判定掉線,只需要send或者recv一下,如果結果為零,則為掉線。但是,在長連線下,有可能很長一段時間都沒有資料往來。理論上說,這個連線是一直保持連線的,但是實際情況中,如果中間節點出現什麼故障是難以知道的。更要命的是,有的節點(防火牆)會自動把一定時間之內沒有資料互動的連線給斷掉。在這個時候,就需要我們的心跳包了,用於維持長連線,保活。

在獲知了斷線之後,伺服器邏輯可能需要做一些事情,比如斷線後的資料清理呀,重新連線呀……當然,這個自然是要由邏輯層根據需求去做了。

總的來說,心跳包主要也就是用於長連線的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。

 

 

相關文章