1. 程式人生 > >《即時訊息技術剖析與實戰》學習筆記8——IM系統如何保證長連線的可用性

《即時訊息技術剖析與實戰》學習筆記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、應用層心跳等方式來檢測,前者可探測網路連線可用性,後者可探測網路和服務的可用性。