幾乎所有的網遊服務端都有心跳包(heartbeat或ping)的設計,在最近開發手遊服務端時,也用到了心跳包。思考思考,心跳包是必須的嗎?為什麼需要心跳包?tcp沒有提供斷線檢測的方法嗎?tcp提供的keepalive機制可以替代heartbeat嗎?
由於連線丟失時,tcp不會立即通知應用程式。比如說,客戶端程式斷線了,服務端的tcp連線不會檢測到斷線,而是一直處於連線狀態。這就帶來了很大的麻煩,明明客戶端已經斷了,服務端還維護著客戶端的連線,照常執行著該玩家的遊戲邏輯……
心跳包就是用來及時檢測是否斷線的一種機制,通過每間隔一定時間傳送心跳資料,來檢測對方是否連線。是屬於應用程式協議的一部分。
問題1: tcp為什麼不自己提供斷線檢測?
首先,斷線檢測需要輪詢傳送檢測報文,會消耗一定的網路頻寬和暫用一定的網路資源。如果把它做成tcp的底層預設功能,那些不需要斷線檢測的應用程式將會浪費不必要的頻寬資源。
另外,tcp不提供連線丟失及時通知的最重要原因與其主要設計目的目標之一有關:出現網路故障時維護通訊的能力。tcp是美國國防部贊助研究的,一種即使發生戰爭或自然災害這種嚴重網路損壞情況下,也能維護可靠網路通訊的網路協議。通常,網路故障只是暫時的,有時路由器會在tcp臨時連線丟失後默默的重新連上。所以,tcp本身並不提供那麼及時的斷線檢測。
問題2: tcp的keepalive機制可以用來及時檢測連線狀態嗎?
tcp有個keepalive開關,開啟後可以用來檢測死連線。通常預設是2小時,可以自己設定。但是注意,這是tcp的全域性設定。假如為了能更及時的檢測出斷開的連線,把tcp_keepalive_time
和tcp_keepalive_intvl
的時間改小(參考:link),該機器上所有應用程式的keepalive檢測間隔都會變小,顯然是不能接受的。因為不同應用程式的需求是不一樣的。
(在某些平台的socket實現已經支援為每條連線單獨設定keepalive引數)
keepalive本質上來說,是用來檢測長時間不活躍的連線的。所以,不適合用來及時檢測連線的狀態。
問題3:心跳包(heartbeat)為什麼是好的方式及時檢測連線狀態?
具有更大的靈活性,可以自己控制檢測的間隔,檢測的方式等等。
心跳包同時適用於tcp和udp,在切換tcp和udp時,上層的心跳包功能都適用。(其實這種情況很少遇到)
有些情況下,心跳包可以附帶一些其他資訊,定時在服務端和客戶端之間同步。(比如幀數同步)
需要及時檢測tcp連線狀態,心跳包(heartbeat)還是必須的。
關於心跳 Heartbeat
最近做了一些服務軟體冗餘的工作。其中的一點就是實現服務冗餘的切換機制,通常採用心跳來實現,我這裡採用的是應用層的自定義心跳協議。心跳協議 heartbeat protocol 是用來監控網路中的節點及確認其正常工作。監控 倆字就要求了 心跳協議的資訊必須包含 狀態描述 和 切換機制描述。在服務冗餘心...
集群基礎 (heartbeat心跳元件)
集群間心跳 heartbeat heartbeat 3.0 4 2.el6.x86 64.rpm heartbeat devel 3.0 4 2.el6.x86 64.rpm heartbeat libs 3.0 4 2.el6.x86 64.rpmyum install y heartbeat 2...
IM為什麼需要心跳
對於客戶端而言,使用 tcp 長連線來實現業務的最大驅動力在於 在當前連線可用的情況下,每一次請求都只是簡單的資料傳送和接受,免去了 dns 解析,連線建立等時間,大大加快了請求的速度,同時也有利於接受伺服器的實時訊息。但前提是連線可用。nat超時是影響tcp連線壽命的乙個重要因素 尤其是國內 所以...