TCP Keepalive機制與應用層心跳Heartbeat

TCP長連接中可能出現的問題

1.     很多防火牆路由器等對於空閒socket自動關閉

2.     對於非正常斷開, 服務器並不能檢測到. 爲了回收資源, 必須提供一種檢測機制.

於是,就有了心跳(HeartBeat)機制。


心跳機制的兩種實現方案

目前而言,有兩種方式實現TCP的保活(業內現狀是IM方面幾乎都採用第一種)

1.     應用層協議自己實現的心跳機制

很多應用層協議都有HeartBeat機制,由應用自己實現的應用層的心跳, 爲心跳消息額外定義一個消息類型。通常是客戶端每隔一小段時間向服務器發送一個數據包,通知服務器自己仍然在線,並傳輸一些可能必要的數據。使用心跳包的典型協議是IM,比如QQ/MSN/飛信等協議。

2.     TCP協議支持的心跳機制Keepalive

打開TCP協議已有的SO_KEEPALIVE選項. 一般實現在服務器側,客戶端被動響應前面一篇博客有具體介紹,這裏就不多講了。

 

TCP Keepalive和應用層HeartBeat優缺點

1.     TCP協議的Keepalive

優點:

系統內核完全替上層應用自動給做好了,內核層面計時器相比上層應用,更爲高效

上層應用只需要處理數據收發、連接異常通知即可。

使用起來簡單, 減少了應用層代碼的複雜度. 也會更節省流量, 因爲應用層的數據傳輸到TCP協議層時都會被加上額外的包頭包尾. 由TCP協議提供的檢活, 其發的探測包, 理論上實現的會更精妙, 耗費更少的流量.。

缺點:

第一點,keepAlive只能檢測連接存活,而不能檢測連接可用,比如某臺服務器因爲某些原因導致負載超高,CPU滿了,無法響應任何業務請求,但是使用 TCP 探針則仍舊能夠確定連接狀態,這就是典型的連接活着但業務提供方已死的狀態,對客戶端而言,這時的最好選擇就是斷線後重新連接其他服務器,而不是一直認爲當前服務器是可用狀態,一直向當前服務器發送些必然會失敗的請求;

第二點,如果tcp連接的另一端突然掉線,這個時候我們並不知道網絡已經關閉。而此時,如果有發送數據失敗,tcp會自動進行重傳。重傳包的優先級高於keepalive的包,那就意味着,我們的keepalive總是不能發送出去。 而此時,我們也並不知道該連接已經出錯而中斷。在較長時間的重傳失敗之後,我們纔會知道。

2.     應用層HeartBeat

優點:

有着更大的靈活性,可以控制檢測時機,間隔和處理流程,甚至可以在心跳包上附帶額外信息,最重要的是可以做到沒有上面所說的缺點,不光可以檢測連接存在,還可以檢測連接可用。

通用, 應用層的心跳不依賴協議. 如果有一天不用TCP要改爲UDP了, 協議層不提供心跳機制了, 但是你應用層的心跳依舊是通用的, 可能只需要做少許改動就可以繼續使用。

缺點:需要自己實現,增加開發工作量,由於應用特定的網絡框架,還可能增加代碼結構的複雜度,應用層心跳的流量消耗還是更大的,畢竟這本質上還是個普通的數據包。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章