為什么說基于TCP的移動端仍然需要心跳保活笋轨?

前言

很多人認(rèn)為秆剪,TCP協(xié)議自身先天就有KeepAlive機(jī)制赊淑,為何基于它的通訊鏈接,仍然需要在應(yīng)用層實現(xiàn)額外的心跳苯龇恚活陶缺?本文將從移動端IM實踐的角度告訴你,即使使用的是TCP協(xié)議洁灵,應(yīng)用層的心跳北グ叮活仍舊必不可少。

什么是心跳被涨В活苫费?

1.jpeg

在使用 TCP 長連接的 IM 服務(wù)設(shè)計中,往往都會涉及到心跳双抽。心跳一般是指某端(絕大多數(shù)情況下是客戶端)每隔一定時間向?qū)Χ税l(fā)送自定義指令百框,以判斷雙方是否存活,因其按照一定間隔發(fā)送荠诬,類似于心跳琅翻,故被稱為心跳指令。

TCP協(xié)議不是自帶KeepAlive的嗎柑贞?

那么問題就隨之而來了:為什么需要在應(yīng)用層做心跳方椎,難道 TCP 不是個可靠連接嗎?我們不能夠依賴 TCP 做斷線檢測嗎钧嘶?比如使用 TCP 的 KeepAlive 機(jī)制來實現(xiàn)棠众。應(yīng)用層心跳是目前的最佳實踐嗎?怎么樣的心跳才是最佳實踐有决。

IM中保持有效長連接的重要性

對于客戶端而言闸拿,使用 TCP 長連接來實現(xiàn)業(yè)務(wù)的最大驅(qū)動力在于:在當(dāng)前連接可用的情況下,每一次請求都只是簡單的數(shù)據(jù)發(fā)送和接受书幕,免去了 DNS 解析新荤,連接建立等時間,大大加快了請求的速度台汇,同時也有利于接受服務(wù)器的實時消息苛骨。但前提是連接可用。

如果連接無法很好地保持苟呐,每次請求就會變成撞大運(yùn):運(yùn)氣好痒芝,通過長連接發(fā)送請求并收到反饋。運(yùn)氣差牵素,當(dāng)前連接已失效严衬,請求遲遲沒有收到反饋直到超時,又需要一次連接建立的過程笆呆,其效率甚至還不如 HTTP请琳。而連接保持的前提必然是檢測連接的可用性粱挡,并在連接不可用時主動放棄當(dāng)前連接并建立新的連接。

基于這個前提单起,必須要有一種機(jī)制用于檢測連接可用性抱怔。同時移動網(wǎng)絡(luò)的特殊性也要求客戶端需要在空余時間發(fā)送一定的信令,避免連接被回收嘀倒。

而對于服務(wù)器而言屈留,能夠及時獲悉連接可用性也非常重要:一方面服務(wù)器需要及時清理無效連接以減輕負(fù)載,另一方面也是業(yè)務(wù)的需求测蘑,如游戲副本中服務(wù)器需要及時處理玩家掉線帶來的問題灌危。

TCP的KeepAlive無法?替代應(yīng)用層心跳保活機(jī)制的原因

上面說了保持連接的重要性碳胳,那么現(xiàn)在回到具體實現(xiàn)上勇蝙。為什么我們需要使用應(yīng)用層心跳來做檢測,而不是直接使用 TCP 的特性呢挨约?

我們知道 TCP 是一個基于連接的協(xié)議味混,其連接狀態(tài)是由一個狀態(tài)機(jī)進(jìn)行維護(hù),連接完畢后诫惭,雙方都會處于 established 狀態(tài)翁锡,這之后的狀態(tài)并不會主動進(jìn)行變化。這意味著如果上層不進(jìn)行任何調(diào)用夕土,一直使 TCP 連接空閑馆衔,那么這個連接雖然沒有任何數(shù)據(jù),但仍是保持連接狀態(tài)怨绣,一天角溃、一星期、甚至一個月篮撑,即使在這期間中間路由崩潰重啟無數(shù)次减细。舉個現(xiàn)實中經(jīng)常遇到的栗子:當(dāng)我們 ssh 到自己的 VPS 上,然后不小心踢掉網(wǎng)線赢笨,此時的網(wǎng)絡(luò)變化并不會被 TCP 檢測出未蝌,當(dāng)我們重新插回網(wǎng)線,仍舊可以正常使用 ssh质欲,同時此時并沒有發(fā)生任何 TCP 的重連。

有人會說 TCP 不是有 KeepAlive 機(jī)制么糠馆,通過這個機(jī)制來實現(xiàn)不就可以了嗎嘶伟?但是事實上,TCP KeepAlive 的機(jī)制其實并不適用于此又碌。Keep Alive 機(jī)制開啟后九昧,TCP 層將在定時時間到后發(fā)送相應(yīng)的 KeepAlive 探針以確定連接可用性绊袋。一般時間為 7200 s(詳情請參見《TCP/IP詳解》中第23章),失敗后重試 10 次铸鹰,每次超時時間 75 s癌别。顯然默認(rèn)值無法滿足我們的需求,而修改過設(shè)置后就可以滿足了嗎蹋笼?答案仍舊是否定的展姐。

因為 TCP KeepAlive 是用于檢測連接的死活,而心跳機(jī)制則附帶一個額外的功能:檢測通訊雙方的存活狀態(tài)剖毯。兩者聽起來似乎是一個意思圾笨,但實際上卻大相徑庭。

考慮一種情況逊谋,某臺服務(wù)器因為某些原因?qū)е仑?fù)載超高擂达,CPU 100%,無法響應(yīng)任何業(yè)務(wù)請求胶滋,但是使用 TCP 探針則仍舊能夠確定連接狀態(tài)板鬓,這就是典型的連接活著但業(yè)務(wù)提供方已死的狀態(tài),對客戶端而言究恤,這時的最好選擇就是斷線后重新連接其他服務(wù)器俭令,而不是一直認(rèn)為當(dāng)前服務(wù)器是可用狀態(tài),一直向當(dāng)前服務(wù)器發(fā)送些必然會失敗的請求丁溅。

從上面我們可以知道唤蔗,KeepAlive 并不適用于檢測雙方存活的場景,這種場景還得依賴于應(yīng)用層的心跳窟赏。應(yīng)用層心跳有著更大的靈活性妓柜,可以控制檢測時機(jī),間隔和處理流程涯穷,甚至可以在心跳包上附帶額外信息棍掐。從這個角度而言,應(yīng)用層的心跳的確是最佳實踐拷况。

心跳弊骰停活機(jī)制的實現(xiàn)方案參考

從上面我們可以得出結(jié)論,目前而言赚瘦,應(yīng)用層心跳的確是檢測連接有效性粟誓,雙方是否存活的最佳實踐,那么剩下的問題就是怎么實現(xiàn)起意。

最簡單粗暴做法當(dāng)然是定時心跳鹰服,如每隔 30 秒心跳一次,15 秒內(nèi)沒有收到心跳回包則認(rèn)為當(dāng)前連接已失效,斷開連接并進(jìn)行重連悲酷。這種做法最直接套菜,實現(xiàn)也簡單。唯一的問題是比較耗電和耗流量设易。以一個協(xié)議包 5 個字節(jié)計算逗柴,一天收發(fā) 2880 個心跳包,一個月就是 5 * 2 * 2880 * 30 = 0.8 M 的流量顿肺,如果手機(jī)上多裝幾個 IM 軟件戏溺,每個月光心跳就好幾兆流量沒了,更不用說頻繁的心跳帶來的電量損耗挟冠。

既然頻繁心跳會帶來耗電和耗流量的弊端于购,改進(jìn)的方向自然是減少心跳頻率,但也不能過于影響連接檢測的實時性知染±呱基于這個需求,一般可以將心跳間隔根據(jù)程序狀態(tài)進(jìn)行調(diào)整控淡,當(dāng)程序在后臺時(這里主要考慮安卓)嫌吠,盡量拉長心跳間隔,5 分鐘掺炭、甚至 10 分鐘都可以辫诅。

而當(dāng) App 在前臺時則按照原來規(guī)則操作。連接可靠性的判斷也可以放寬涧狮,避免一次心跳超時就認(rèn)為連接無效的情況炕矮,使用錯誤積累,只在心跳超時 n 次后才判定當(dāng)前連接不可用者冤。當(dāng)然還有一些小 trick 比如從收到的最后一個指令包進(jìn)行心跳包周期計時而不是固定時間肤视,這樣也能夠一定程度減少心跳次數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涉枫,一起剝皮案震驚了整個濱河市邢滑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌愿汰,老刑警劉巖困后,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異衬廷,居然都是意外死亡摇予,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門吗跋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侧戴,“玉大人,你說我怎么就攤上這事【壤穑” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵秩冈,是天一觀的道長本缠。 經(jīng)常有香客問我,道長入问,這世上最難降的妖魔是什么丹锹? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮芬失,結(jié)果婚禮上楣黍,老公的妹妹穿的比我還像新娘。我一直安慰自己棱烂,他們只是感情好租漂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著颊糜,像睡著了一般哩治。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衬鱼,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天业筏,我揣著相機(jī)與錄音,去河邊找鬼鸟赫。 笑死蒜胖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抛蚤。 我是一名探鬼主播台谢,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼霉颠!你這毒婦竟也來了对碌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蒿偎,失蹤者是張志新(化名)和其女友劉穎朽们,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诉位,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骑脱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苍糠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叁丧。...
    茶點(diǎn)故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拥娄,到底是詐尸還是另有隱情蚊锹,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布稚瘾,位于F島的核電站牡昆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏摊欠。R本人自食惡果不足惜丢烘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望些椒。 院中可真熱鬧播瞳,春花似錦、人聲如沸免糕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽石窑。三九已至骏全,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尼斧,已是汗流浹背姜贡。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棺棵,地道東北人楼咳。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像烛恤,于是被迫代替她去往敵國和親母怜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1缚柏、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)苹熏、netstat -nat 查看TCP各個狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,437評論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理币喧,服務(wù)發(fā)現(xiàn)轨域,斷路器,智...
    卡卡羅2017閱讀 134,711評論 18 139
  • 18.1 引言 TCP是一個面向連接的協(xié)議杀餐。無論哪一方向另一方發(fā)送數(shù)據(jù)之前干发,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,390評論 0 13
  • 長連接和心跳那些事兒 簡書 滌生史翘。轉(zhuǎn)載請注明原創(chuàng)出處枉长,謝謝冀续!如果讀完覺得有收獲的話,歡迎點(diǎn)贊加關(guān)注必峰。 介紹 長連接...
    滌生YQ閱讀 11,726評論 2 69
  • ?我走過你走過的路算不算重逢 洪唐,我吹過你吹過的風(fēng)算不算相擁! 姑娘吼蚁,我在這條小巷見過你桐罕, 穿著花裙子,陽光下的微笑...
    貳十三先生閱讀 457評論 6 7