《即時訊息技術剖析與實戰》學習筆記8——IM系統如何保證長連線的可用性
假設有以下突發意外情況:
- 使用者進入訊號不好的地方,手機沒有網路訊號了
- 上網的路由器突然掉線了
這個時候,比如微信發訊息,訊息就會轉圈圈,甚至變成紅色歎號……
上面情況都會導致“長連線”不可用。
我們知道,為了讓訊息能更加實時、可靠、快速地觸達到接收方,大部分 IM 系統會通過“長連線”的方式來建立收發雙方的通訊通道,長連線一旦建立,就一直存在,除非網路被中斷。
有了這基於 TCP 長連線的通訊協議,在使用者上線連線時,可以在服務端維護好連線到伺服器的使用者裝置和具體 TCP 連線的對映關係,服務端也能通過這個對映關係隨時找到對應線上的使用者的客戶端。對於傳送方來說,傳送訊息也能通過“長連線”通道把訊息給到 IM 服務端。
一、什麼是心跳機制
但長連線並不是永久可用的,當長連線在中間鏈路出問題時,為了不使使用者感知到,應快速通知連線的兩端,並重新建立新的可用連線,從而使長連線一直保持“高可用”狀態,這個能夠快速、不間斷識別連線可用性的機制,稱為“心跳機制”。
“心跳機制”會持續地往連線傳送“模擬資料”,一方面是為了試探連線的可用性,另一方面也是為了保證資料的持續流通,讓連線在沒有真正業務資料收發的情況下,不會被中間的網路運營商以為連線沒有被使用而切斷連線。
二、心跳機制的優點
1. 降低服務端開銷
訊息之所以能夠實現“服務端推送”,是因為針對每一臺上線的裝置,都會在 IM 服務端維護相應的 使用者裝置<->網路連線
若沒有心跳機制,當長連線異常而 IM 服務端無法感知到,會產生兩種不良後果:
- 無效的長連線一直在被維護,不管是連線控制代碼,還是快取大量“對映關係”、“裝置狀態”等資訊,都會導致資源浪費;
- 向無效連線推送訊息,以及後續的重試推送,都會降低服務的整體效能。
2. 支援客戶端斷線重連
當客戶端和 IM 服務端之間的網路在中間某些環節斷開,或伺服器負載過高,則會出現客戶端在一定的超時時間內,發出的心跳包得不到 IM 服務端響應的現象,這時客戶端就可以認為和服務端的長連線不可用,自動斷線重連,保持長連線的可用性。
3. 連線保活
即使使用者網路和中間路由網路都正常,若一直沒有資料收發,運營商就會將這個長連線清除掉,來降低自身閘道器的壓力,這個清除動作不會被客戶端和 IM 服務端感知到,為了避免被運營商幹掉,客戶端會在沒有訊息收發的空閒時間給服務端傳送心跳包,使長連線存活時間更長。
三、心跳檢測的方式
1. TCP Keepalive
Keepalive 並不是 TCP 協議的一部分,但大多數作業系統都實現了這個機制,作業系統預設是關閉這個特性的,需要由應用層來開啟。TCP 的 keepalive 會在連線空閒期按一定的頻次,自動傳送不攜帶資料的探測報文,來探測對方是否存活。
Keepalive 預設是關閉的,開啟 Keepalive 需要在 TCP 的 socket 中單獨開啟,作業系統層面有三個引數影響到 Keepalive 的行為:
tcp_keepalive_time 7200 // 心跳週期:距離上次傳送資料多少時間未收到新報文判斷為開始檢測,單位秒,預設7200s
tcp_keepalive_intvl 75 // 超時時間:檢測開始每多少時間傳送心跳包,單位秒,預設75s
tcp_keepalive_probes 9 // 失敗後重試次數:傳送幾次心跳包對方未響應則close連線,預設9次
優點:
- 易用性好:作為系統層 TCP/IP 協議層的已有實現,不需要其他開發工作量,上層應用只需要處理探測後的連線異常情況即可。
- 網路消耗小:心跳包不攜帶資料,頻寬資源浪費少。
缺點:
- 心跳間隔靈活性差:一臺伺服器某一時間只能調整為固定間隔的心跳。
- 結果反映差:可以探測網路連線層的存活,但並不代表真正的應用層處於可用狀態,即網路仍然是通的,但應用已不可用。
2. 應用層心跳
應用層心跳實際上是客戶端每隔一定時間間隔,向 IM 服務端傳送一個業務層的資料包告知自身存活。如果 IM 服務端在一定時間內沒有收到心跳包,就認定客戶端由於某種原因連線不可達了,此時就會從 IM 服務端把這個連線斷開,同時清除相應分配的其他資源。
優點:
- 心跳間隔靈活性強:應用層心跳可以根據實際網路的情況,來靈活設定心跳間隔,節省網路流量。
- 結果反饋準:由於需要在應用層進行傳送和接收的處理,不僅能代表網路可用,更能反映應用的可用性。
缺點:
- 額外的資料傳輸開銷(非常小)。
- 實現邏輯根據心跳策略而定,有的實現起來略複雜。
3. 智慧心跳
心跳間隔能夠根據網路環境自動調整,逐步逼近 NAT 超時臨界點,在保證 NAT 不超時的情況下儘量節約裝置資源,常見的有二分法。但需要權衡使用。
四、小結
- 能夠快速、不間斷識別連線可用性的機制,稱為“心跳機制”。
- 心跳機制可以降低服務端連線維護無效連線的開銷,支援客戶端快速識別無效連線、自動斷線重連,連線保活,避免被運營商 NAT 超時斷開。
- 心跳可以使用 TCP Keepalive、應用層心跳等方式來檢測,前者可探測網路連線可用性,後者可探測網路和服務的可用性。