閒說HeartBeat心跳包和TCP協議的KeepAlive機制

不少應用層協議都有HeartBeat機制,一般是客戶端每隔一小段時間向服務器發送一個數據包,通知服務器本身仍然在線,並傳輸一些可能必要的數據。使用心跳包的典型協議是IM,好比QQ/MSN/飛信等協議。

學過TCP/IP的同窗應該都知道,傳輸層的兩個主要協議是UDP和TCP,其中UDP是無鏈接的、面向packet的,而TCP協議是有鏈接、面向流的協議。

因此很是容易理解,使用UDP協議的客戶端(例如早期的「OICQ」,據說OICQ.com這兩天被搶注了來着,好古老的回憶)須要定時向服務器發送心跳包,告訴服務器本身在線。

然而,MSN和如今的QQ每每使用的是TCP鏈接了,儘管TCP/IP底層提供了可選的KeepAlive(ACK-ACK包)機制,可是它們也仍是實現了更高層的心跳包。彷佛既浪費流量又浪費CPU,有點莫名其妙。

具體查了下,TCP的KeepAlive機制是這樣的,首先它貌似默認是不打開的,要用setsockopt將SOL_SOCKET.SO_KEEPALIVE設置爲1纔是打開,而且能夠設置三個參數tcp_keepalive_time/tcp_keepalive_probes/tcp_keepalive_intvl,分別表示鏈接閒置多久開始發keepalive的ack包、發幾個ack包不回覆才當對方死了、兩個ack包之間間隔多長,在我測試的Ubuntu Server 10.04下面默認值是7200秒(2個小時,要不要這麼蛋疼啊!)、9次、75秒。因而鏈接就了有一個超時時間窗口,若是鏈接之間沒有通訊,這個時間窗口會逐漸減少,當它減少到零的時候,TCP協議會向對方發一個帶有ACK標誌的空數據包(KeepAlive探針),對方在收到ACK包之後,若是鏈接一切正常,應該回復一個ACK;若是鏈接出現錯誤了(例如對方重啓了,鏈接狀態丟失),則應當回覆一個RST;若是對方沒有回覆,服務器每隔intvl的時間再發ACK,若是連續probes個包都被無視了,說明鏈接被斷開了。

這裏有一篇很是詳細的介紹文章: http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO ,包括了KeepAlive的介紹、相關內核參數、C編程接口、如何爲現有應用(能夠或者不能夠修改源碼的)啓用KeepAlive機制,很值得詳讀。

這篇文章的2.4節說的是「Preventing disconnection due to network inactivity」,阻止因網絡鏈接不活躍(長時間沒有數據包)而致使的鏈接中斷,說的是,不少網絡設備,尤爲是NAT路由器,因爲其硬件的限制(例如內存、CPU處理能力),沒法保持其上的全部鏈接,所以在必要的時候,會在鏈接池中選擇一些不活躍的鏈接踢掉。典型作法是LRU,把最久沒有數據的鏈接給T掉。經過使用TCP的KeepAlive機制(修改那個time參數),可讓鏈接每隔一小段時間就產生一些ack包,以下降被T掉的風險,固然,這樣的代價是額外的網絡和CPU負擔

前面說到,許多IM協議實現了本身的心跳機制,而不是直接依賴於底層的機制,不知道真正的緣由是什麼。

就我看來,一些簡單的協議,直接使用底層機制就能夠了,對上層徹底透明,下降了開發難度,不用管理鏈接對應的狀態。而那些本身實現心跳機制的協議,應該是指望經過發送心跳包的同時來傳輸一些數據,這樣服務端能夠獲知更多的狀態。例如某些客戶端很喜歡收集用戶的信息……反正是要發個包,不如再塞點數據,不然包頭又浪費了……

大概就是這樣吧,若是有大牛知道真正的緣由,還望不吝賜教。


@2012-04-21 

p.s. 經過諮詢某個作過IM的同事,參考答案應該是,本身實現的心跳機制通用,能夠無視底層的UDP或TCP協議。若是隻是用TCP協議的話,那麼直接使用KeepAlive機制就足夠了

@2015-09-14
補充一下 @Jack的回覆:
心跳除了說明應用程序還活着(進程還在,網絡通暢),更重要的是代表應用程序還能正常工做。而 TCP keepalive 有操做系統負責探查,即使進程死鎖,或阻塞,操做系統也會如常收發 TCP keepalive 消息。對方沒法得知這一異常。摘自《Linux 多線程服務端編程》」php

1.KeepAlive機制不少狀況沒法檢測出來,如網絡鏈接被軟件禁用等,不夠可靠,網絡狀態複雜的狀況下這種狀況尤爲嚴重。2.本身實現心跳能夠加入更靈活與實用的機制,好比少了一個心跳,能夠立刻再次檢查,檢查間隔遞減,這樣能夠更快的感知網絡狀態,而不是等待固定的時間。html

--編程

 


轉載請註明出自 http://www.felix021.com/blog/read.php?2076 ,如是轉載文則註明原出處,謝謝:)服務器

相關文章
相關標籤/搜索