中文字幕在线视频第一页,黄色毛片在线看,日本爱爱网站,亚洲系列中文字幕一区二区

您當前的位置是:  首頁 > 資訊 > 國內 >
 首頁 > 資訊 > 國內 >

【融云分析】 IM 即時通訊之鏈路保活

2019-04-10 16:51:44   作者:   來源:CTI論壇   評論:0  點擊:


  眾所周知,IM 即時通訊是一項對即時性要求非常高的技術,而保障消息即時到達的首要條件就是鏈路存活。那么在復雜的網(wǎng)絡環(huán)境和國內安卓手機被深度定制化的條件下,如何保障鏈路存活呢?本文詳解了融云安卓端 SDK 在基于 TCP 協(xié)議實現(xiàn)鏈路保活方面的探索和經(jīng)驗。
  IM 系統(tǒng)整體框架
  如上圖所示,為了保障鏈路存活,一套成熟的 IM 系統(tǒng)一般會包含消息鏈路和推送鏈路兩條長連接通道。當有新消息到達時,消息服務首先會判斷消息鏈路是否存活,如果消息鏈路處于存活狀態(tài),消息優(yōu)先從消息鏈路下發(fā)到客戶端,否則會被路由到推送服務器,由推送鏈路下發(fā)。
  綜上所述,鏈路保活涉及到消息鏈路和推送鏈路兩條鏈路的保活策略。基于這兩條鏈路使用場景的不同,保活策略上除了心跳機制是相同的,其它保活策略各有不同。下文將逐一解讀。
  鏈路保活的必要性
  基于 TCP 的 Socket 連接建立之后,如果不做任何處理,這個連接會長時間存在并且可用嗎?答案是否定的。原因有兩點:
  一、默認Socket 連接無法及時探測到鏈路的異常情況,即使將 Socket 的屬性參數(shù) KeepAlive 設置為 True 仍然無法及時獲取到鏈路存活狀態(tài)。這是因為 Socket 的連接狀態(tài)是由一個狀態(tài)機進行維護的,連接完畢后,雙方都會處于建立狀態(tài)。假如某臺服務器因為某些原因導致負載超高,無法及時響應業(yè)務請求,這時 TCP 探測到的仍然是連接狀態(tài),而實際上此鏈路已經(jīng)不可用了。
  二、國內運營商的 NAT 超時機制會把一定時間內沒有數(shù)據(jù)交互的連接斷開,這個時間可能只有幾分鐘,遠無法滿足我們的長連接需求。
  通用保活機制-心跳機制
  基于以上原因,要維持 Socket 連接長時間存活,就需要實現(xiàn)自己的保活機制。最通用的一種保活機制就是心跳機制。即客戶端每隔一段時間給服務器發(fā)送一個很小的數(shù)據(jù)包,根據(jù)能否收到服務器的響應來判斷鏈路的可用性。為了節(jié)省流量,這個包一般非常小,甚至沒有內容。
  那么客戶端如何實現(xiàn)定時發(fā)送心跳包呢?一般有兩種方式:
  一種是通過 Java 里的 Timer 來實現(xiàn)。最基本的步驟如下:
  1. 建立一個要執(zhí)行的任務 TimerTask 。
  2. 創(chuàng)建一個 Timer 實例,通過 Timer 提供的 schedule() 方法,將 TimerTask 加入到定時器 Timer 中,設置每隔一段時間執(zhí)行 TimerTask , 在 TimerTask 里發(fā)送心跳包。這種方式實現(xiàn)起來較簡單,而且省電,不需要持有 WakeLock 。缺點也很明顯,長時間在后臺,進程被回收或者系統(tǒng)休眠后, Timer 機制隨之失效。
  另外一種方式是利用安卓系統(tǒng)的定時任務管理器 AlarmManager 循環(huán)執(zhí)行發(fā)送心跳包的任務。這種方式不會因為系統(tǒng)休眠而失效,系統(tǒng)休眠后仍然可以通過 WakeLock 喚醒,執(zhí)行心跳任務,因此相對 Timer 機制,這種方式比較費電,使用的時候一定要注意如下幾點:
  • 首先根據(jù)需求合理使用 AlarmManager 的鬧鐘參數(shù)。鬧鐘各參數(shù)的區(qū)別參考下表:
  • 其次 AlarmManager 提供了 cancel() 方法,在設置新的定時任務前,通過 cancel() 方法取消系統(tǒng)里設置的同類型任務,避免設置冗余任務。
  • 最后,安卓從 6.0 版本引入了 Doze 模式,并提供了新的鬧鐘設置方法 setExactAndAllowWhileIdle() ,通過該方法設置的鬧鐘時間,系統(tǒng)會智能調度,將各個應用設置的事務統(tǒng)一在一次喚醒中處理,以達到省電的目的。推薦在安卓 6.0 以上系統(tǒng)中,優(yōu)先使用該方法。
  消息鏈路保活機制
  消息鏈路作為收發(fā)消息的主要通道,需要最大程度保障鏈路的可用性。在鏈路不可用或者異常斷開時,能及時探測并啟動重連等保障機制。基于以上特性,消息鏈路除了前面所說的心跳機制外,還另外維護了兩套鏈路優(yōu)化機制:復合連接機制和重連機制。
  復合連接機制的基本步驟如下:
  1. 客戶端連接導航服務器,導航服務器會下發(fā)應用對應的配置信息,其中包括連接服務器的地址列表。
  2. 客戶端從第一個服務器地址嘗試連接,并啟動超時機制,如果連接失敗或沒有及時收到服務響應, 則繼續(xù)嘗試連接下一個直到成功連接,將成功連接的地址保存到本地,作為最優(yōu)地址,后面連接時優(yōu)先使用此地址。通過這種機制,能保障客戶端優(yōu)先選用最優(yōu)鏈路,縮短連接時間。
  重連機制,則是指業(yè)務層在檢測到與服務器的連接斷開后,嘗試 N 次重新連接服務器,首次斷開 1 秒后會重新連接,如果仍然連接不成功,會在 2 秒后(重連間隔時間為上次重連間隔時間乘 2  )嘗試重新連接服務器,以此類推當嘗試重連 N 次后,仍然連不上服務器將不再嘗試重新連接,只有在網(wǎng)絡情況發(fā)生變化或重新打開應用時才會再次嘗試重連。
  推送鏈路保活機制
  推送鏈路作為消息到達的補充手段,要求盡可能延長在后臺的存活時間。即使被殺后,仍然能被再次喚醒。 iOS 手機有 APNS 來達到以上效果,但安卓的官方推送系統(tǒng) FCM 在國內基本不可用。那在國內安卓系統(tǒng)上如何保障推送到達呢?首先咱們需要先了解下安卓系統(tǒng)上進程管理的兩大機制:
  一種是 LMK 機制,英文是 Low Memory Killer , 基于 Linux 的內存管理機制衍生而來。主要是通過進程的 oom_adj 值來判定進程的重要程度,從而決定是否回收這些進程。 oom_adj 的值越低,代表重要度越高,比如 native 進程, framework 層啟動的系統(tǒng)進程,優(yōu)先級一般都為負數(shù)。其次是前臺可見進程,系統(tǒng)也不會回收。然而可見進程退到后臺后, oom_adj 的值會立即升高,在系統(tǒng)定時清理時被殺。
  另外一種機制是安卓原生的權限管理機制( AppOps ),各大廠家在此基礎上又進行了深度定制化,比如小米的安全中心,華為的手機管家等,都用來進行權限管理。該權限管理機制運行在安卓系統(tǒng)的框架層,上層各應用的進程如果想嘗試重新啟動,系統(tǒng)首先會去權限管理中心檢查該進程有沒有自啟動權限,如果有,才準予啟動。否則,從框架層直接限制系統(tǒng)的啟動。
  基于以上兩種機制,推送鏈路的保活也可分為兩大類:
  一、進程保活。它的思路是根據(jù) LMK 機制提高進程優(yōu)先級,降低被殺的幾率。主要有以下幾種方法:
  • 監(jiān)聽黑屏事件,啟動 1 像素透明 Activity ,使應用進程轉為可視進程,降低被殺概率。在屏幕亮時,關閉該 Activity 。
  • 雙服務守護。 A 服務以 startForeground() 形式啟動,發(fā)送一個通知, B 服務同樣以  startForeground() 形式啟動,且發(fā)送和 A 相同 ID 的通知,然后在 B 服務里調用 stopForeground() 方法,取消通知。這樣 A 服務就會以前臺進程的形式存活,且不影響用戶感知。
  • 根據(jù)文件鎖互斥原理,監(jiān)視 Java  進程存活狀態(tài),若被殺, Linux 層成功持有文件,則通過 exec() 命令,打開一個純 Linux 的可執(zhí)行文件,開啟一個 Daemon 進程, 該進程因為從 Linux 層啟動,在安卓 5.0 之前,優(yōu)先級會比較高,不會被殺。在安卓 5.0 之后,該方式不再有效。
  二、進程拉活的策略和安卓系統(tǒng)的 AppOps 機制有關,一般有如下幾種:
  • 利用 Service 本身的 Sticky 屬性,在 Service 的 onStartCommand() 中返回 START_STICKY ,這樣當 Service 被殺掉后,系統(tǒng)會自動嘗試重啟。不過在國內定制化的系統(tǒng)上,這種方式能成功重啟的幾率很低,需要用戶在權限管理中心打開自啟動等權限,才能成功拉活。
  • 也就是前面講過的心跳機制,不過這里要求使用 AlarmManager 設置  ELAPSED_REALTIME_WAKEUP 屬性的鬧鐘,在系統(tǒng)休眠后,才會正常接受到心跳事件,從而將進程拉活。
  • 通過監(jiān)聽網(wǎng)絡切換,用戶行為等事件,拉起進程。
  • 應用間互相拉活。比如系統(tǒng)里有好幾個應用集成了同一個 SDK , 那么在用戶啟動其中某一個 App 的時候, SDK 會去掃描其它應用,把“兄弟姐妹” 拉活。這種方式對用戶體驗傷害非常大,會造成系統(tǒng)莫名其妙的耗電。
  隨著安卓系統(tǒng)版本的迭代,對后臺進程的啟動管控越來越嚴。為了解決推送的問題,各手機廠家推出了自己的系統(tǒng)級推送服務。由廠家在 Framework 層統(tǒng)一維護一條推送通道,上層所有應用共同使用該推送鏈路,不需要再維護單獨進程。當前支持系統(tǒng)級推送的廠家有:小米、華為、魅族、 vivo 、OPPO ,集成第三方系統(tǒng)級推送之后,整個消息的收發(fā)流程可以參考下圖:
  這種系統(tǒng)級別的推送省電,省內存,到達率高。應用可以根據(jù)手機型號的不同,優(yōu)先使用廠家系統(tǒng)級別的推送,再配合自身的保活機制,最大程度保障推送的到達率。
【免責聲明】本文僅代表作者本人觀點,與CTI論壇無關。CTI論壇對文中陳述、觀點判斷保持中立,不對所包含內容的準確性、可靠性或完整性提供任何明示或暗示的保證。請讀者僅作參考,并請自行承擔全部責任。

專題

CTI論壇會員企業(yè)

红桥区| 田东县| 南阳市| 当阳市| 漳浦县| 屏边| 无为县| 安溪县| 西吉县| 内乡县| 巴马| 绥中县| 陈巴尔虎旗| 抚顺县| 太仓市| 敖汉旗| 吉水县| 汨罗市| 酉阳| 宁化县| 光泽县| 乌兰察布市| 泾阳县| 鹤岗市| 安新县| 伊吾县| 景东| 城市| 迁西县| 高阳县| 玉树县| 共和县| 仪陇县| 宜城市| 五河县| 布尔津县| 兴宁市| 开江县| 凤山市| 中阳县| 凤阳县|