什么是微信的Mars
Mars是微信在2017年開源的一套跨平臺(tái)跨業(yè)務(wù)的基礎(chǔ)組件。在這里可以給出github上的官方架構(gòu)圖
從上面的架構(gòu)圖中我們可以看到雄妥,Mars主要包含了一下幾個(gè)部分:
STN:STN是微信的網(wǎng)絡(luò)傳輸信令模塊淑际,是mars組件中終端和服務(wù)端進(jìn)行通訊的小數(shù)據(jù)信令通道探遵。STN模塊包含了微信在海量用戶使用上作出的一系列優(yōu)化和嘗試,特別是在弱網(wǎng)絡(luò)情況下有非常不錯(cuò)的效果
SDT:Mars的網(wǎng)絡(luò)診斷工具钙勃,這里包含了Mars對(duì)當(dāng)前網(wǎng)絡(luò)狀態(tài)的定義叭披,包括:優(yōu)質(zhì)網(wǎng)颅筋、正常網(wǎng)和弱網(wǎng)絡(luò)等的界定置逻。這對(duì)于下面我們要進(jìn)行分析的智能心跳和STN超時(shí)機(jī)制有非常密切的關(guān)系推沸。
XLOG:基于mmap讀寫的一套日志框架,具體的分析可以看我之前的一篇文章
騰訊Xlog接入指南與踩過的坑
Comm:主要包含了消息隊(duì)列券坞,鎖坤学,時(shí)鐘還有線程管理等,基礎(chǔ)Comm不在本次的分析介紹之內(nèi)
為什么要使用Mars
通過研究和學(xué)習(xí)报慕,為什么要使用Mars我這里做了幾點(diǎn)小結(jié)
1 如果你的應(yīng)用只是一個(gè)普通的APP,并不涉及到即時(shí)通訊压怠,或者你們的APP對(duì)于消息的即時(shí)性沒有很強(qiáng)的要求眠冈,那么我比較推薦你只單獨(dú)使用Mars的Xlog組件就可以了。這對(duì)你們app的日志管理菌瘫,線上問題追蹤和定位具有非常好的幫助蜗顽。在接入了Xlog后,出現(xiàn)線上問題我們上家公司幾乎可以做到5分鐘內(nèi)定位問題雨让,10分鐘給出解決方案雇盖。
2 STN組件的設(shè)計(jì)邏輯非常的貼合移動(dòng)互聯(lián)網(wǎng)的網(wǎng)絡(luò)使用環(huán)境,是一套非常成功的解決方案栖忠,尤其是弱網(wǎng)環(huán)境和平臺(tái)特性具有非常多的優(yōu)化策略
3 Mars 是基于socket的解決方案崔挖,在網(wǎng)絡(luò)調(diào)優(yōu)方面具有跟強(qiáng)的主動(dòng)性和可控性贸街。
Mars 的超時(shí)機(jī)制
TCP的超時(shí)重傳
熟悉TCP傳輸協(xié)議的同學(xué)都知道,TCP在建立連接的情況下狸相,如果當(dāng)前的請(qǐng)求方?jīng)]有在規(guī)定的時(shí)間內(nèi)得到接收方的相應(yīng)薛匪,那么就會(huì)發(fā)生重傳的機(jī)制,這個(gè)也是TCP保證可靠性傳輸?shù)囊粋€(gè)重要的原則脓鹃。我們?cè)诹私獬瑫r(shí)和重傳是需要了解的兩個(gè)指標(biāo)
RTT:數(shù)據(jù)往返的時(shí)間逸尖;
RTO:超時(shí)重傳的時(shí)間間隔
這里盜一張mars的官方圖,我們來看下Android手機(jī)的tcp超時(shí)重傳的時(shí)間間隔表現(xiàn)
從途中我們可以看到瘸右,超時(shí)重傳的間隔娇跟,依次為[ 0.25s,0.5s太颤,1s苞俘,2s,4s栋齿,8s苗胀,16s,32s瓦堵,64s基协,64s,64s …]
我們可以看到菇用,前面的重傳時(shí)間還有一定的時(shí)間間隔澜驮,但后面是幾個(gè)連續(xù)的64s。這個(gè)算法其實(shí)就是指數(shù)退避的算法惋鸥。
Mars的超時(shí)重傳機(jī)制
是不是傳輸層已經(jīng)有了超時(shí)重傳機(jī)制杂穷,應(yīng)用層就不需要了呢?其實(shí)不是的卦绣,我們可以知道tcp在經(jīng)過一定的超時(shí)重傳后才會(huì)確定當(dāng)前的tcp不可用耐量,返回timeout標(biāo)示。但是這個(gè)時(shí)間非常的就滤港,一般來說Android手機(jī)大概要6min才會(huì)確定當(dāng)前的TCP連接不可用廊蜒。但是對(duì)于移動(dòng)端來說6min的時(shí)間是非常影響用戶體驗(yàn)的,因此應(yīng)用層的超時(shí)重傳機(jī)制需要更加的敏捷溅漾。
但是需要注意山叮,敏捷并不等于密集。在很多的場(chǎng)景下添履,密集的心跳機(jī)制并不能取到重新建連的效果屁倔,反而會(huì)是網(wǎng)絡(luò)通道更加的惡劣。因此在經(jīng)過多個(gè)嘗試后暮胧,Mars采用了一下的幾個(gè)超時(shí)方案
總讀寫超時(shí)
總讀寫時(shí)間這個(gè)比較好理解锐借,就是一次完成的RTT所需要的時(shí)間问麸,這里總結(jié)起來包括:
請(qǐng)求發(fā)送耗時(shí) - 類比TCP包傳輸耗時(shí);
響應(yīng)信令接收耗時(shí) - 類比ACK傳輸耗時(shí)瞎饲;
服務(wù)器處理請(qǐng)求耗時(shí) - TCP接收端接收和處理數(shù)據(jù)包的時(shí)間相對(duì)固定口叙,而服務(wù)器由于信令所屬業(yè)務(wù)的不同,邏輯處理的耗時(shí)會(huì)差異明顯嗅战,所以無法類比妄田;
等待耗時(shí) - 受應(yīng)用中請(qǐng)求并發(fā)數(shù)影響。
因此驮捍,我們提出了應(yīng)用層的總讀寫超時(shí)如右圖所示疟呐,最低網(wǎng)速根據(jù)不同的網(wǎng)絡(luò)取不同的值。
首包超時(shí)
總讀寫超時(shí)有一個(gè)弊端是無法確定服務(wù)端的處理請(qǐng)求時(shí)間东且,最致命的一點(diǎn)是相應(yīng)信令的時(shí)間處理較長(zhǎng)启具,這導(dǎo)致了在網(wǎng)絡(luò)狀態(tài)很差的情況下,同樣需要較長(zhǎng)的時(shí)間才可以進(jìn)行重試珊泳。首包超時(shí)是指在tcp的第一次回包的情況就去確定這個(gè)信令的接受耗時(shí)鲁冯。調(diào)整后的首包超時(shí)方案如下
包包超時(shí)
首包超時(shí)有一個(gè)弊端,就是在網(wǎng)絡(luò)堵塞的情況下色查,由于tcp的擁塞窗口和流量控制薯演,一個(gè)tcp包會(huì)被切割成幾個(gè)部分進(jìn)行傳輸,也就是發(fā)生了tcp的拆包和粘包的現(xiàn)象秧了。加入后續(xù)的包又丟失了跨扮,仍然需要整個(gè)完整的讀寫超時(shí)才能發(fā)生問題。這就引入了包包超時(shí)的機(jī)制:兩個(gè)數(shù)據(jù)段之間的超時(shí)時(shí)間验毡。因?yàn)榘瑫r(shí)在首包超時(shí)之后衡创,這個(gè)階段已經(jīng)確認(rèn)服務(wù)器收到了請(qǐng)求,且完成了請(qǐng)求的處理晶通,因此不需要計(jì)算等待耗時(shí)璃氢、請(qǐng)求傳輸耗時(shí)、服務(wù)器處理耗時(shí)狮辽,只需要估算網(wǎng)絡(luò)的 RTT一也。
動(dòng)態(tài)超時(shí)
動(dòng)態(tài)讀寫超級(jí)更多的是依賴于當(dāng)前的網(wǎng)絡(luò)狀況,這個(gè)網(wǎng)絡(luò)狀態(tài)評(píng)估就跟之前提到的SDT模塊有著莫大的關(guān)系隘竭。Mars在動(dòng)態(tài)超時(shí)的設(shè)計(jì)中,把當(dāng)前的網(wǎng)絡(luò)分為excellent和evaluate兩種狀態(tài)讼渊,分別在這兩種狀態(tài)中不停的調(diào)整當(dāng)前的動(dòng)態(tài)耗時(shí)动看。
Mars 的連接方案-復(fù)合連接
我們先總結(jié)一下串行連接和并行的優(yōu)缺點(diǎn)
串行連接:
1 資源占用小,服務(wù)端沒有負(fù)載的壓力
2 超時(shí)選擇困難爪幻,連接最慢可用
并行連接
1 資源占用較大菱皆,服務(wù)端負(fù)債壓力大
2 連接最快可用
復(fù)合連接
先看一下官方給的圖
初始階段须误,應(yīng)用發(fā)起對(duì) IP1 &Port1 的 connect 調(diào)用。在第4秒的時(shí)候仇轻,如果第一個(gè) connect 還沒有返回京痢,則發(fā)起對(duì) IP2 &Port2 的 connect 調(diào)用。以此類推篷店,直至發(fā)起了5組 IP&Port 的 connect 調(diào)用祭椰。
對(duì)比串行連接與并行連接,復(fù)合連接有以下特點(diǎn):
常規(guī)情況下疲陕,服務(wù)器負(fù)載與串行連接策略相同方淤,實(shí)現(xiàn)了低負(fù)載的目標(biāo);
異常情況下蹄殃,每4s發(fā)起新(IP携茂,Port)組合的 connect 調(diào)用,使得應(yīng)用可以快速的查找可用 IP&Port诅岩,實(shí)現(xiàn)高性能的目標(biāo)讳苦;
在超時(shí)時(shí)間的選擇上,復(fù)合方式的“并發(fā)”已經(jīng)實(shí)現(xiàn)了高性能吩谦、低負(fù)載的目標(biāo)鸳谜,因此在超時(shí)時(shí)間的選擇上可以相對(duì)寬松,以保障高可用為重逮京。
綜合對(duì)比卿堂,復(fù)合連接能夠維持低資源消耗的情況下,能同時(shí)實(shí)現(xiàn)低負(fù)載懒棉、高性能草描、高可用的目標(biāo)。
Mars的智能心跳
智能心跳指的是長(zhǎng)連接過程中策严,應(yīng)用層維護(hù)的自己和服務(wù)端的心跳連接穗慕。客戶端在適當(dāng)?shù)臅r(shí)間周期內(nèi)妻导,向服務(wù)端發(fā)送一個(gè)心跳請(qǐng)求逛绵,判斷當(dāng)前的連接是否可用。一般的app處理是用一個(gè)定時(shí)的任務(wù)(45s)連續(xù)的向服務(wù)端發(fā)送ping請(qǐng)求倔韭,等待服務(wù)端的返回术浪。如果心痛不同,則認(rèn)為當(dāng)前的長(zhǎng)連接不可用寿酌,需要重新進(jìn)行長(zhǎng)連接的建聯(lián)胰苏。
微信的智能心跳如下
心跳時(shí)間區(qū)間:最小4分30秒,最大9分50秒醇疼;
心跳增加步長(zhǎng):60秒硕并;心跳穩(wěn)定后法焰,探測(cè)步長(zhǎng):20秒;
當(dāng)前APP為活躍狀態(tài)倔毙,長(zhǎng)連剛連接前3個(gè)成功心跳埃仪,和沒有網(wǎng)絡(luò),這3種情況使用固定最小心跳:4分30秒陕赃;其他情況使用自適應(yīng)智能心跳卵蛉,基本算法如下;
連續(xù)3個(gè)心跳成功后凯正,每心跳增加60秒心跳步長(zhǎng)毙玻,一直到最大9分50秒,設(shè)為固定狀態(tài)廊散;
連續(xù)3個(gè)心跳失敗后桑滩,減少60+20秒,第4個(gè)心跳失敗允睹,直接設(shè)最小心跳4分30秒运准;