03.06 在以TCP為連接方式的服務器中,為什麼在服務端設計當中需要考慮心跳?

河北解放


“我是喲喲吼說科技,專注於數據網絡的回答,歡迎大家與我交流數據網絡的問題”

心跳機制是在數據通信連接中,定時發送一個自定義結構的心跳報文,讓對端清楚自己還在線,保證連接的有效性。

如題,服務器端在設計心跳的主要目的就是為了探測對端是否還正常在線,兩端都可以發送心跳的報文,主要通過此方式去判斷用戶側是否在線,若不在線則對服務器端的緩存數據進行清理,即主動對用戶進行下線操作。以遊戲服務端為例做舉例:

當用戶登錄某遊戲進行試玩,因為其它原因長時間掛機,沒有操作,這時服務器端與客戶端就會交互心跳報文,證明此用戶還在線,因此會保證用戶連接狀態,但也可以設置對應時間段內若沒有任何操作進行下線處理;

當用戶登錄遊戲後,因為其它原因造成主機非正常關機,沒有根據正常的操作步驟去下線,這時就會通過心跳報文來判斷主機是否正常在線,若不在線即可直接進行下線處理。

個人認為,應用層的心跳報文與TCP連接的Keep-alive機制在功能上是一樣的效果,但是TCP的的這種機制存在弊端(如:在TCP建立連接後啟用定時器,若沒到定時器設置的時間點發生中斷,那麼TCP不能及時將連接斷開),而應用層的心跳機制可以設置數據發送的頻率,因此心跳報文的功能只是負責告訴對方我在線,而不需要進行其它功能的交互。

歡迎大家多多關注我,在下方評論區說出自己的見解。


喲喲吼說科技


心跳主要目的是探活。應用於移動場合最核心的作用是:防止基站移除私有IP的NAT映射表條目。

原因

NAT(Network Address Translation)的作用你懂的,在互聯網上,只有公網IP才能路由無阻,我們的私有IP需要路由器設備代理:有公網IP的路由器用為我們分配一個端口,用這個端口和服務端通信;對於服務端來說,和它建立連接的並不是我們自己的機器,而是路由器。

路由器我們可以暫時不討論,這個NAT失效的概率很小。我們來看看基站。

假如市中心有一個移動的基站,人來人往,車來車往,大家的手機進入基站區域,通過基站連接到了某些服務器,然後短時間又離開了基站。基站NAT可用的端口有限的,最大65535(理論值)個。如果NAT映射表不清除那些短暫連入基站的條目,一旦映射表滿了,後續就無法再提供NAT服務了。

所以,基站一般設置較短的NAT失效時間(3分鐘左右),超過這個時間,如果這個端口沒有收發數據,就會移除端口,對應的TCP連接就失效了!心跳的作用剛好就可以延長NAT條目保存的時間。

還有問題

即使你使用了心跳也不能100%保證客戶端成功接收,只是說成功概率更大了而已。

為什麼?因為我們的心跳間隔一般不會太小,否則變相DOS攻擊自己的服務器。在心跳間隔期間,連接失效,我們的推送一樣失敗。最悲傷的情況是剛心跳完,就失效了。

另外你要弱化連接的概念,網絡中並不存在一條固定保持的鏈路,只是雙方主機各自為連接保持了一個端口而已。真實網絡中,這個數據能不能真正路由到對方,雙方只有在收發數據的時候才能確認。所以,我們面向互聯網的服務器,有很多的半連接存在(我們的服務認為對方還在線)!這個也是心跳存在的最大理由。而基站nat是面向移動端的最常見的問題!所以面向移動應用保持長鏈接,我們的心跳時間會略小於基站NAT失效時間!

心跳對資源的消耗比較大,移動端要注意為用戶省流量,省電,探活也不能太坑用戶。


遷徙de麻雀


心跳

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

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

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

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

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

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

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


IT老記者


心跳機制主要考慮服務器資源及時回收,要知道服務器端併發要求是很高的,每一個TCP鏈接都會在服務器端分配相應的內存資源,如果客戶端已經掉線,但是服務器卻不知道,不能及時釋放資源,再進來新的鏈接,由於沒有足夠的內存資源分配,可能導致拒絕服務的問題


分享到:


相關文章: