深入了解微信Mars基礎(chǔ)組件

什么是微信的Mars

Mars是微信在2017年開(kāi)源的一套跨平臺(tái)跨業(yè)務(wù)的基礎(chǔ)組件。在這里可以給出github上的官方架構(gòu)圖

Mars基礎(chǔ)架構(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讀寫(xiě)的一套日志框架,具體的分析可以看我之前的一篇文章
騰訊Xlog接入指南與踩過(guò)的坑
Comm:主要包含了消息隊(duì)列,鎖,時(shí)鐘還有線程管理等,基礎(chǔ)Comm不在本次的分析介紹之內(nèi)

為什么要使用Mars

通過(guò)研究和學(xué)習(xí),為什么要使用Mars我這里做了幾點(diǎn)小結(jié)
1 如果你的應(yīng)用只是一個(gè)普通的APP,并不涉及到即時(shí)通訊,或者你們的APP對(duì)于消息的即時(shí)性沒(méi)有很強(qiáng)的要求,那么我比較推薦你只單獨(dú)使用Mars的Xlog組件就可以了。這對(duì)你們app的日志管理,線上問(wèn)題追蹤和定位具有非常好的幫助。在接入了Xlog后,出現(xiàn)線上問(wèn)題我們上家公司幾乎可以做到5分鐘內(nèi)定位問(wèn)題,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的官方圖,我們來(lái)看下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)過(guò)一定的超時(shí)重傳后才會(huì)確定當(dāng)前的tcp不可用,返回timeout標(biāo)示。但是這個(gè)時(shí)間非常的就,一般來(lái)說(shuō)Android手機(jī)大概要6min才會(huì)確定當(dāng)前的TCP連接不可用。但是對(duì)于移動(dòng)端來(lái)說(shuō)6min的時(shí)間是非常影響用戶體驗(yàn)的,因此應(yīng)用層的超時(shí)重傳機(jī)制需要更加的敏捷。
但是需要注意,敏捷并不等于密集。在很多的場(chǎng)景下,密集的心跳機(jī)制并不能取到重新建連的效果,反而會(huì)是網(wǎng)絡(luò)通道更加的惡劣。因此在經(jīng)過(guò)多個(gè)嘗試后,Mars采用了一下的幾個(gè)超時(shí)方案

總讀寫(xiě)超時(shí)

總讀寫(xiě)時(shí)間這個(gè)比較好理解,就是一次完成的RTT所需要的時(shí)間,這里總結(jié)起來(lái)包括:
請(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ì)差異明顯,所以無(wú)法類比;
等待耗時(shí) - 受應(yīng)用中請(qǐng)求并發(fā)數(shù)影響。
因此,我們提出了應(yīng)用層的總讀寫(xiě)超時(shí)如右圖所示,最低網(wǎng)速根據(jù)不同的網(wǎng)絡(luò)取不同的值。

總讀寫(xiě)超時(shí)

首包超時(shí)

總讀寫(xiě)超時(shí)有一個(gè)弊端是無(wú)法確定服務(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í)

首包超時(shí)有一個(gè)弊端,就是在網(wǎng)絡(luò)堵塞的情況下,由于tcp的擁塞窗口和流量控制,一個(gè)tcp包會(huì)被切割成幾個(gè)部分進(jìn)行傳輸,也就是發(fā)生了tcp的拆包和粘包的現(xiàn)象。加入后續(xù)的包又丟失了,仍然需要整個(gè)完整的讀寫(xiě)超時(shí)才能發(fā)生問(wèn)題。這就引入了包包超時(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)讀寫(xiě)超時(shí)

動(dòng)態(tài)讀寫(xiě)超級(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í)。


網(wǎng)絡(luò)情況診斷

Mars 的連接方案-復(fù)合連接

我們先總結(jié)一下串行連接和并行的優(yōu)缺點(diǎn)
串行連接
1 資源占用小,服務(wù)端沒(méi)有負(fù)載的壓力
2 超時(shí)選擇困難,連接最慢可用
并行連接
1 資源占用較大,服務(wù)端負(fù)債壓力大
2 連接最快可用
復(fù)合連接
先看一下官方給的圖

復(fù)合連接

初始階段,應(yīng)用發(fā)起對(duì) IP1 &Port1 的 connect 調(diào)用。在第4秒的時(shí)候,如果第一個(gè) connect 還沒(méi)有返回,則發(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)連接過(guò)程中,應(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è)成功心跳,和沒(méi)有網(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秒;


微信心跳機(jī)制.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容