《即時消息技術剖析與實戰》學習筆記8——IM系統如何保證長連接的可用性

假設有以下突發意外情況:

  • 用戶進入信號不好的地方,手機沒有網絡信號了
  • 上網的路由器突然掉線了
    這個時候,比如微信發消息,消息就會轉圈圈,甚至變成紅色歎號……
    上面情況都會導致“長連接”不可用。

我們知道,爲了讓消息能更加實時、可靠、快速地觸達到接收方,大部分 IM 系統會通過“長連接”的方式來建立收發雙方的通信通道,長連接一旦建立,就一直存在,除非網絡被中斷。

有了這基於 TCP 長連接的通信協議,在用戶上線連接時,可以在服務端維護好連接到服務器的用戶設備和具體 TCP 連接的映射關係,服務端也能通過這個映射關係隨時找到對應在線的用戶的客戶端。對於發送方來說,發送消息也能通過“長連接”通道把消息給到 IM 服務端。

一、什麼是心跳機制

但長連接並不是永久可用的,當長連接在中間鏈路出問題時,爲了不使用戶感知到,應快速通知連接的兩端,並重新建立新的可用連接,從而使長連接一直保持“高可用”狀態,這個能夠快速、不間斷識別連接可用性的機制,稱爲“心跳機制”。

“心跳機制”會持續地往連接發送“模擬數據”,一方面是爲了試探連接的可用性,另一方面也是爲了保證數據的持續流通,讓連接在沒有真正業務數據收發的情況下,不會被中間的網絡運營商以爲連接沒有被使用而切斷連接。

二、心跳機制的優點

1. 降低服務端開銷

消息之所以能夠實現“服務端推送”,是因爲針對每一臺上線的設備,都會在 IM 服務端維護相應的 用戶設備<->網絡連接 這樣的映射關係,除此之外,爲了節省網絡開銷,還會在服務端臨時緩存一些不用每次請求都攜帶的客戶端信息,如 app 版本號、操作系統、網絡狀態等,甚至還會在服務端維護一些“用戶在線狀態”和“所有在線設備”這些信息,便於業務使用,這樣客戶端一旦建好長連接,只需要首次攜帶這些信息,後續請求可以不用再攜帶,而是使用 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、應用層心跳等方式來檢測,前者可探測網絡連接可用性,後者可探測網絡和服務的可用性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章