微信團(tuán)隊(duì)分享:微信后臺(tái)在海量并發(fā)請(qǐng)求下是如何做到不崩潰的

本文引用了文章“月活 12.8 億的微信是如何防止崩潰的?”和論文“Overload Control for Scaling WeChat Microservices”的內(nèi)容,有大量改動(dòng)、優(yōu)化和修訂。
1、引言
微信是一款國(guó)民級(jí)的即時(shí)通訊IM應(yīng)用,月活用戶早就超過(guò)10億,而且經(jīng)常過(guò)年過(guò)節(jié)會(huì)遇到聊天消息量暴增的情況,服務(wù)是很容易出現(xiàn)過(guò)載的,但事實(shí)是微信的后臺(tái)服務(wù)一直比較穩(wěn)定,那么他們是怎么做到的呢?
本文以微信發(fā)表的論文《Overload Control for Scaling Wechat Microservices》 為基礎(chǔ)(論文PDF原文下載見文末附件),分享了微信基于大規(guī)模微服務(wù)架構(gòu)的后臺(tái)過(guò)載管控和保護(hù)策略,以及微信根據(jù)IM業(yè)務(wù)特點(diǎn)的一些獨(dú)特的架構(gòu)設(shè)計(jì)做法,其中很多方法很有借鑒意義,值得一讀。

?(本文已同步發(fā)布于:http://www.52im.net/thread-3930-1-1.html)
2、微信所面臨的并發(fā)壓力
截止論文《Overload Control for Scaling Wechat Microservices》發(fā)表前,微信后端有超過(guò)3000多個(gè)服務(wù)(包括即時(shí)聊天、社交關(guān)系、移動(dòng)支付和第三方授權(quán)等),占用20000多臺(tái)機(jī)器(隨著微信的廣泛普及,這些數(shù)字仍在不斷增加)。
面向前端請(qǐng)求的入口服務(wù)每天需要處理10億到100億級(jí)別的請(qǐng)求,而每個(gè)這樣的請(qǐng)求還會(huì)觸發(fā)更多內(nèi)部的關(guān)聯(lián)服務(wù),從整體來(lái)看,微信后端需要每秒處理數(shù)億個(gè)請(qǐng)求。
隨著微信的不斷發(fā)展,這些服務(wù)子系統(tǒng)一直在快速進(jìn)行更新迭代。以2018 年的3月到5月為例,在短短的兩個(gè)月時(shí)間里,微信的各服務(wù)子系統(tǒng)平均每天發(fā)生近千次的變更,運(yùn)維壓力可想而之。
另外:微信每天請(qǐng)求量的分布很不平均,高峰期請(qǐng)求量能達(dá)到平時(shí)的3倍。而在特殊日子里(比如過(guò)年的時(shí)候),高峰期的流量能飆升到平時(shí)的10倍。有時(shí)朋友圈里有什么刷屏的活動(dòng),流量肯定也會(huì)突增。由此可見,微信后端系統(tǒng)的并發(fā)壓力相當(dāng)之大。
而且:微信后端的這些服務(wù)所處的環(huán)境也是不斷變化的,包括硬件故障、代碼bug、系統(tǒng)變更等,都會(huì)導(dǎo)致服務(wù)可承受的容量動(dòng)態(tài)變化。
3、微信的后端服務(wù)架構(gòu)
微信后端采用的也是微服務(wù)架構(gòu)。說(shuō)是微服務(wù),其實(shí)我理解就是采用統(tǒng)一的 RPC 框架搭建的一個(gè)個(gè)獨(dú)立的服務(wù),服務(wù)之間互相調(diào)用,實(shí)現(xiàn)各種各樣的功能,這也是現(xiàn)代服務(wù)的基本架構(gòu)。畢竟誰(shuí)也不希望看到我朋友圈崩了,導(dǎo)致跟我聊天也不行了,這也是微信的典型好處。
微信后端的微服務(wù)架構(gòu)一般分為3層:

如上圖所示,這3層服務(wù)分別是:
1)“入口跳板”服務(wù)(接收外部請(qǐng)求的前端服務(wù));
2)“共享跳板”服務(wù)(中間層協(xié)調(diào)服務(wù));
3)“基礎(chǔ)服務(wù)”(不再向其他服務(wù)發(fā)出請(qǐng)求的服務(wù),也就是充當(dāng)請(qǐng)求的接收器)。
微信后端的大多數(shù)服務(wù)屬于“共享跳板”服務(wù),“入口跳板”服務(wù)比如登錄、發(fā)送聊天消息、支付服務(wù)等?!盎A(chǔ)服務(wù)”也就是日常最好理解的這些信息數(shù)據(jù)接口類,比如賬戶數(shù)據(jù)、個(gè)人信息、好友/聯(lián)系人信息等。
按照微信后端服務(wù)的請(qǐng)求量(每日在十億到百億之間),入口協(xié)議觸發(fā)對(duì)“共享跳板”服務(wù)和“基礎(chǔ)服務(wù)”更多的請(qǐng)求,核心服務(wù)每秒要處理上億次的請(qǐng)求,也就是顯而易見的了。
4、什么是過(guò)載保護(hù)
1)什么是服務(wù)過(guò)載?
服務(wù)過(guò)載就是服務(wù)的請(qǐng)求量超過(guò)服務(wù)所能承受的最大值,從而導(dǎo)致服務(wù)器負(fù)載過(guò)高,響應(yīng)延遲加大。
用戶側(cè)表現(xiàn)就是無(wú)法加載或者加載緩慢,這會(huì)引起用戶進(jìn)一步的重試,服務(wù)一直在處理過(guò)去的無(wú)效請(qǐng)求,導(dǎo)致有效請(qǐng)求跌 0,甚至導(dǎo)致整個(gè)系統(tǒng)產(chǎn)生雪崩。
2)為什么會(huì)發(fā)生服務(wù)過(guò)載?
互聯(lián)網(wǎng)天生就會(huì)有突發(fā)流量、秒殺、搶購(gòu)、突發(fā)大事件、節(jié)日甚至惡意攻擊等,都會(huì)造成服務(wù)承受平時(shí)數(shù)倍的壓力,比如微博經(jīng)常出現(xiàn)某明星官宣結(jié)婚或者離婚導(dǎo)致服務(wù)器崩潰的場(chǎng)景,這就是服務(wù)過(guò)載。
3)過(guò)載保護(hù)的好處
過(guò)載保護(hù)主要是為了提升用戶體驗(yàn),保障服務(wù)質(zhì)量,在發(fā)生突發(fā)流量時(shí)仍然能夠提供一部分服務(wù)能力,而不是整個(gè)系統(tǒng)癱瘓。
系統(tǒng)癱瘓就意味著用戶流失、口碑變差、夫妻吵架,甚至威脅生命安全(假如騰訊文檔崩潰,這個(gè)文檔正好用于救災(zāi))。
而微信團(tuán)隊(duì)在面對(duì)這種量級(jí)的高并發(fā)請(qǐng)求挑戰(zhàn),做法是精細(xì)化的服務(wù)過(guò)載控制。我們繼續(xù)往下學(xué)習(xí)。
5、微信面臨的過(guò)載控制技術(shù)挑戰(zhàn)
過(guò)載控制對(duì)于大規(guī)模在線應(yīng)用程序來(lái)說(shuō)至關(guān)重要,這些應(yīng)用程序需要在不可預(yù)測(cè)的負(fù)載激增的情況下實(shí)現(xiàn) 24×7 服務(wù)可用性。
傳統(tǒng)的過(guò)載控制機(jī)制是為具有少量服務(wù)組件、相對(duì)狹窄的“前門”和普通依賴關(guān)系的系統(tǒng)而設(shè)計(jì)的。
而微信這種現(xiàn)代即時(shí)通訊im應(yīng)用的全時(shí)在線服務(wù)特性,在架構(gòu)和依賴性方面正變得越來(lái)越復(fù)雜,遠(yuǎn)遠(yuǎn)超出了傳統(tǒng)過(guò)載控制的設(shè)計(jì)目標(biāo)。
這些技術(shù)痛點(diǎn)包括:
1)由于發(fā)送到微信后端的服務(wù)請(qǐng)求沒有單一的入口點(diǎn),因此傳統(tǒng)的全局入口點(diǎn)(網(wǎng)關(guān))集中負(fù)載監(jiān)控方法并不適用;
2)特定請(qǐng)求的服務(wù)調(diào)用圖可能依賴于特定于請(qǐng)求的數(shù)據(jù)和服務(wù)參數(shù),即使對(duì)于相同類型的請(qǐng)求也是如此(因此,當(dāng)特定服務(wù)出現(xiàn)過(guò)載時(shí),很難確定應(yīng)該限制哪些類型的請(qǐng)求以緩解這種情況);
3)過(guò)多的請(qǐng)求中止浪費(fèi)了計(jì)算資源,并由于高延遲而影響了用戶體驗(yàn);
4)由于服務(wù)的調(diào)用鏈極其復(fù)雜,而且在不斷演化,導(dǎo)致有效的跨服務(wù)協(xié)調(diào)的維護(hù)成本和系統(tǒng)開銷過(guò)高。
由于一個(gè)服務(wù)可能會(huì)向它所依賴的服務(wù)發(fā)出多個(gè)請(qǐng)求,并且還可能向多個(gè)后端服務(wù)發(fā)出請(qǐng)求,因此我們必須特別注意過(guò)載控制。我們使用一個(gè)專門的術(shù)語(yǔ),叫作“后續(xù)過(guò)載”,用于描述調(diào)用多個(gè)過(guò)載服務(wù)或多次調(diào)用單個(gè)過(guò)載服務(wù)的情況。
“后續(xù)過(guò)載”給有效的過(guò)載控制帶來(lái)了挑戰(zhàn)。當(dāng)服務(wù)過(guò)載時(shí)隨機(jī)執(zhí)行減載可以讓系統(tǒng)維持飽和的吞吐量,但后續(xù)過(guò)載可能會(huì)超預(yù)期大大降低系統(tǒng)吞吐量 …
即:在大規(guī)模微服務(wù)場(chǎng)景下,過(guò)載會(huì)變得比較復(fù)雜,如果是單體服務(wù),一個(gè)事件只用一個(gè)請(qǐng)求,但微服務(wù)下,一個(gè)事件可能要請(qǐng)求很多的服務(wù),任何一個(gè)服務(wù)過(guò)載失敗,就會(huì)造成其他的請(qǐng)求都是無(wú)效的。如下圖所示。

?比如:在一個(gè)轉(zhuǎn)賬服務(wù)下,需要查詢分別兩者的卡號(hào), 再查詢 A 時(shí)成功了,但查詢 B 失敗,對(duì)于查卡號(hào)這個(gè)事件就算失敗了。比如查詢成功率只有 50%, 那對(duì)于查詢兩者卡號(hào)這個(gè)成功率只有 50% * 50% = 25% 了, 一個(gè)事件調(diào)用的服務(wù)次數(shù)越多,那成功率就會(huì)越低。
6、微信的過(guò)載控制機(jī)制
微信的微服務(wù)過(guò)載控制機(jī)制叫“DAGOR”(因?yàn)槲⑿虐阉姆?wù)間關(guān)系模型叫“directed acyclic graph ”,簡(jiǎn)稱DAG)。
顯然這種微服務(wù)底層的機(jī)制必須是和具體的業(yè)務(wù)實(shí)現(xiàn)無(wú)關(guān)的。DAGOR還必須是去中心化的,否則的話在微信這么大且分布不均的流量下,過(guò)載控制很難做到實(shí)時(shí)和準(zhǔn)確。同時(shí)也無(wú)法適應(yīng)微服務(wù)快速的功能迭代發(fā)布(平均每天要發(fā)生近1000次的微服務(wù)上下線)。
此外,DAGOR還需要解決一個(gè)問(wèn)題:服務(wù)調(diào)用鏈很長(zhǎng),如果底層服務(wù)因?yàn)檫^(guò)載保護(hù)丟棄了請(qǐng)求,上層服務(wù)耗費(fèi)的資源全浪費(fèi)了,而且很影響用戶體驗(yàn)(想想進(jìn)度條走到99%告訴你失敗了)。所以過(guò)載控制機(jī)制在各服務(wù)之間必須有協(xié)同作用,有時(shí)候需要考慮整個(gè)調(diào)用鏈的情況。
首先我們來(lái)看怎么檢測(cè)到服務(wù)過(guò)載。
7、微信如何判斷過(guò)載
通常判斷過(guò)載可以使用吞吐量、延遲、CPU 使用率、丟包率、待處理請(qǐng)求數(shù)、請(qǐng)求處理事件等等。
微信使用在請(qǐng)求在隊(duì)列中的平均等待時(shí)間作為判斷標(biāo)準(zhǔn)。平均等待時(shí)間就是從請(qǐng)求到達(dá),到開始處理的時(shí)間。
為啥不使用響應(yīng)時(shí)間?因?yàn)轫憫?yīng)時(shí)間是跟服務(wù)相關(guān)的,很多微服務(wù)是鏈?zhǔn)秸{(diào)用,響應(yīng)時(shí)間是不可控的,也是無(wú)法標(biāo)準(zhǔn)化的,很難作為一個(gè)統(tǒng)一的判斷依據(jù)。
那為什么也不使用 CPU 負(fù)載作為判斷標(biāo)準(zhǔn)呢??因?yàn)?CPU 負(fù)載高不代表服務(wù)過(guò)載,因?yàn)橐粋€(gè)服務(wù)請(qǐng)求處理及時(shí),CPU 處于高位反而是比較良好的表現(xiàn)。實(shí)際上 CPU 負(fù)載高,監(jiān)控服務(wù)是會(huì)告警出來(lái),但是并不會(huì)直接進(jìn)入過(guò)載處理流程。
騰訊微服務(wù)默認(rèn)的超時(shí)時(shí)間是 500ms,通過(guò)計(jì)算每秒或每 2000 個(gè)請(qǐng)求的平均等待時(shí)間是否超過(guò) 20ms,判斷是否過(guò)載,這個(gè) 20ms 是根據(jù)微信后臺(tái) 5 年摸索出來(lái)的門檻值。
采用平均等待時(shí)間還有一個(gè)好處是:獨(dú)立于服務(wù),可以應(yīng)用于任何場(chǎng)景,而不用關(guān)聯(lián)于業(yè)務(wù),可以直接在框架上進(jìn)行改造。
當(dāng)平均等待時(shí)間大于 20ms 時(shí),以一定的降速因子過(guò)濾調(diào)部分請(qǐng)求,如果判斷平均等待時(shí)間小于 20ms,則以一定的速率提升通過(guò)率,一般采用快降慢升的策略,防止大的服務(wù)波動(dòng),整個(gè)策略相當(dāng)于一個(gè)負(fù)反饋電路。
?

8、微信的過(guò)載控制策略
微信后臺(tái)一旦檢測(cè)到服務(wù)過(guò)載,就需要按照一定的過(guò)載保戶策略對(duì)請(qǐng)求進(jìn)行過(guò)濾控制,來(lái)決定哪些請(qǐng)求能被過(guò)載服務(wù)處理,哪些是需要丟棄的。
前面我們分析過(guò),對(duì)于鏈?zhǔn)秸{(diào)用的微服務(wù)場(chǎng)景,隨機(jī)丟棄請(qǐng)求會(huì)導(dǎo)致整體服務(wù)的成功率很低。所以請(qǐng)求是按照優(yōu)先級(jí)進(jìn)行控制的,優(yōu)先級(jí)低的請(qǐng)求會(huì)優(yōu)先丟棄。
那么從哪些維度來(lái)進(jìn)行優(yōu)化級(jí)的分級(jí)呢?
8.1 基于業(yè)務(wù)的優(yōu)先級(jí)控制
對(duì)于微信來(lái)說(shuō),不同的業(yè)務(wù)場(chǎng)景優(yōu)先級(jí)是不同的, 比如:
1)登錄場(chǎng)景是最重要的業(yè)務(wù)(不能登錄一切都白瞎);
2)支付消息比普通im聊天消息優(yōu)先級(jí)高(因?yàn)橛脩魧?duì)金錢是更敏感的);
3)普通消息又比朋友圈消息優(yōu)先級(jí)高(必竟微信的本質(zhì)還是im聊天)。
所以在微信內(nèi)是天然存在業(yè)務(wù)優(yōu)先級(jí)的。
微信的做法是,預(yù)先定義好所有業(yè)務(wù)的優(yōu)先級(jí)并保存在一個(gè)Hash Table里:

沒有定義的業(yè)務(wù),默認(rèn)是最低優(yōu)先級(jí)。
業(yè)務(wù)優(yōu)先級(jí)在各個(gè)業(yè)務(wù)的入口服務(wù)(Entry Services)中找到請(qǐng)求元信息里。由于一個(gè)請(qǐng)求成功與否依賴其下游服務(wù)所有的后續(xù)請(qǐng)求,所以下游服務(wù)的所有后續(xù)請(qǐng)求也會(huì)帶上相同的業(yè)務(wù)優(yōu)先級(jí)。當(dāng)服務(wù)過(guò)載時(shí),會(huì)處理優(yōu)先級(jí)更高的請(qǐng)求,丟棄優(yōu)先級(jí)低的請(qǐng)求。
然而,只用業(yè)務(wù)優(yōu)先級(jí)決定是否丟棄請(qǐng)求,容易造成系統(tǒng)顛簸,比如:
1)支付請(qǐng)求突然上漲導(dǎo)致過(guò)載,消息請(qǐng)求被丟棄;
2)丟棄消息請(qǐng)求后,系統(tǒng)負(fù)載降低了,又開始處理消息請(qǐng)求;
3)然而,處理消息請(qǐng)求又導(dǎo)致服務(wù)過(guò)載,又會(huì)在下一個(gè)窗口拋棄消息請(qǐng)求。
這樣反復(fù)調(diào)整服務(wù)請(qǐng)求管制,整體體驗(yàn)非常不好。所以微信需要更精細(xì)化的服務(wù)請(qǐng)求管制。
PS:微信嘗試過(guò)提供API讓服務(wù)提供方自己修改業(yè)務(wù)優(yōu)先級(jí),后來(lái)在實(shí)踐中發(fā)現(xiàn)這種做法在不同的團(tuán)隊(duì)中極難管理,且對(duì)于過(guò)載控制容易出錯(cuò),最終放棄了。
8.2 基于用戶的優(yōu)先級(jí)控制
很明顯,正如上節(jié)內(nèi)容所述,只基于業(yè)務(wù)優(yōu)先級(jí)的控制是不夠的:
1)首先不可能因?yàn)樨?fù)載高,丟棄或允許通過(guò)一整個(gè)業(yè)務(wù)的請(qǐng)求,因?yàn)槊總€(gè)業(yè)務(wù)的請(qǐng)求量很大,那一定會(huì)造成負(fù)載的大幅波動(dòng);
2)另外如果在業(yè)務(wù)中隨機(jī)丟棄請(qǐng)求,在過(guò)載情況下還是會(huì)導(dǎo)致整體成功率很低。
為了解決這個(gè)問(wèn)題,微信引入用戶優(yōu)先級(jí)。
微信在每個(gè)業(yè)務(wù)優(yōu)先級(jí)內(nèi)按用戶ID計(jì)算出的128個(gè)優(yōu)先級(jí):

首先用戶優(yōu)先級(jí)也不應(yīng)該相同,對(duì)于普通人來(lái)說(shuō)通過(guò) hash 用戶唯一 ID計(jì)算用戶優(yōu)先級(jí)(這個(gè)hash函數(shù)每小時(shí)變一次,讓所有用戶都有機(jī)會(huì)在相對(duì)較長(zhǎng)的時(shí)間內(nèi)享受到高優(yōu)先級(jí),保證“公平”)。跟業(yè)務(wù)優(yōu)先級(jí)一樣,單個(gè)用戶的訪問(wèn)鏈條上的優(yōu)先級(jí)總是一致的。
這里有個(gè)疑問(wèn):為啥不采用會(huì)話 ID 計(jì)算優(yōu)先級(jí)呢?
從理論上來(lái)說(shuō)采用會(huì)話 ID 和用戶 ID 效果是一樣的,但是采用會(huì)話 ID 在用戶重新登錄時(shí)刷新,這個(gè)時(shí)候可能用戶的優(yōu)先級(jí)可能變了。在過(guò)載的情況下,他可能因?yàn)樘岣吡藘?yōu)先級(jí)就恢復(fù)了。
這樣用戶會(huì)養(yǎng)成壞習(xí)慣,在服務(wù)有問(wèn)題時(shí)就會(huì)重新登錄,這樣無(wú)疑進(jìn)一步加劇了服務(wù)的過(guò)載情況。
于是,因?yàn)橐肓擞脩魞?yōu)先級(jí),那就和業(yè)務(wù)優(yōu)先級(jí)組成了一個(gè)二維控制平面。根據(jù)負(fù)載情況,決定這臺(tái)服務(wù)器的準(zhǔn)入優(yōu)先級(jí)(B,U),當(dāng)過(guò)來(lái)的請(qǐng)求業(yè)務(wù)優(yōu)先級(jí)大于 B,或者業(yè)務(wù)優(yōu)先級(jí)等于 B,但用戶優(yōu)先級(jí)高于 U 時(shí),則通過(guò),否則決絕。
下圖就是這個(gè)“優(yōu)先級(jí)(B,U)”控制邏輯(我們會(huì)在后面再具體討論):

8.3 自適應(yīng)優(yōu)先級(jí)調(diào)整
在大規(guī)模微服務(wù)場(chǎng)景下,服務(wù)器的負(fù)載變化是非常頻繁的。所以服務(wù)器的準(zhǔn)入優(yōu)先級(jí)是需要?jiǎng)討B(tài)變化的,微信分了幾十個(gè)業(yè)務(wù)優(yōu)先級(jí),每個(gè)業(yè)務(wù)優(yōu)先級(jí)下有 128 個(gè)用戶優(yōu)先級(jí),所以總的優(yōu)先級(jí)是幾千個(gè)。
如何根據(jù)負(fù)載情況調(diào)整優(yōu)先級(jí)呢?
最簡(jiǎn)單的方式是從右到左遍歷:每調(diào)整一次判斷下負(fù)載情況。這個(gè)時(shí)間復(fù)雜度是 O(n), 就算使用二分法,時(shí)間復(fù)雜度也為 O(logn),在數(shù)千個(gè)優(yōu)先級(jí)下,可能需要數(shù)十次調(diào)整才能確定一個(gè)合適的優(yōu)先級(jí),每次調(diào)整好再統(tǒng)計(jì)優(yōu)先級(jí),可能幾十秒都過(guò)去了,這個(gè)方法無(wú)疑是非常低效的。
微信提出了一種基于直方圖統(tǒng)計(jì)的方法快速調(diào)整準(zhǔn)入優(yōu)先級(jí):服務(wù)器上維護(hù)者目前準(zhǔn)入優(yōu)先級(jí)下,過(guò)去一個(gè)周期的(1s 或 2000 次請(qǐng)求)每個(gè)優(yōu)先級(jí)的請(qǐng)求量。當(dāng)過(guò)載時(shí),通過(guò)消減下一個(gè)周期的請(qǐng)求量來(lái)減輕負(fù)載。假設(shè)上一個(gè)周期所有優(yōu)先級(jí)的通過(guò)的請(qǐng)求總和是 N,下一個(gè)周期的請(qǐng)求量要減少 N*a,怎么去減少呢?每提升一個(gè)優(yōu)先級(jí)就減少一定的請(qǐng)求量,一直提升到 減少的數(shù)目大于目標(biāo)量,恢復(fù)負(fù)載使用相反的方法,只不是系數(shù)為 b ,比 a 小,也是為了快降慢升。根據(jù)經(jīng)驗(yàn)值 a 為 5%,b 為 1%。

為了進(jìn)一步減輕過(guò)載機(jī)器的壓力,能不能在下游過(guò)載的情況下不把請(qǐng)求發(fā)到下游呢?否則下游還是要接受請(qǐng)求、解包、丟棄請(qǐng)求,白白的浪費(fèi)帶寬,也加重了下游的負(fù)載。
為了實(shí)現(xiàn)這個(gè)能力:在每次請(qǐng)求下游服務(wù)時(shí),下游把當(dāng)前服務(wù)的準(zhǔn)入優(yōu)先級(jí)返回給上游,上游維護(hù)下游服務(wù)的準(zhǔn)入優(yōu)先級(jí),如果發(fā)現(xiàn)請(qǐng)求優(yōu)先級(jí)達(dá)不到下游服務(wù)的準(zhǔn)入門檻,直接丟棄,而不再請(qǐng)求下游,進(jìn)一步減輕下游的壓力。
9、實(shí)驗(yàn)數(shù)據(jù)
微信的這套服務(wù)過(guò)載控制策略(即DAGOR)在微信的生產(chǎn)環(huán)境已經(jīng)運(yùn)作多年,這是對(duì)它的設(shè)計(jì)可行性的最好證明。
但并沒有為學(xué)術(shù)論文提供必要的圖表,所以微信同時(shí)進(jìn)行了一組模擬實(shí)驗(yàn)。
下面的圖表突出顯示了基于排隊(duì)時(shí)間而非響應(yīng)時(shí)間的過(guò)載控制的好處。在發(fā)生后續(xù)過(guò)載的情況下,這些好處最為明顯(圖右)。

10、小結(jié)一下
微信的整個(gè)過(guò)載控制邏輯流程如下圖所示:

針對(duì)上面這張圖,我們來(lái)解讀一下:
1)當(dāng)用戶從微信發(fā)起請(qǐng)求,請(qǐng)求被路由到接入層服務(wù),分配統(tǒng)一的業(yè)務(wù)和用戶優(yōu)先級(jí),所有到下游的字請(qǐng)求都繼承相同的優(yōu)先級(jí);
2)根據(jù)業(yè)務(wù)邏輯調(diào)用 1 個(gè)或多個(gè)下游服務(wù),當(dāng)服務(wù)收到請(qǐng)求,首先根據(jù)自身服務(wù)準(zhǔn)入優(yōu)先級(jí)判斷請(qǐng)求是接受還是丟棄(服務(wù)本身根據(jù)負(fù)載情況周期性的調(diào)整準(zhǔn)入優(yōu)先級(jí));
3)當(dāng)服務(wù)需要再向下游發(fā)起請(qǐng)求時(shí),判斷本地記錄的下游服務(wù)準(zhǔn)入優(yōu)先級(jí)(如果小于則丟棄,如果沒有記錄或優(yōu)先級(jí)大于記錄則向下游發(fā)起請(qǐng)求);
4)下游服務(wù)返回上游服務(wù)需要的信息,并且在信息中攜帶自身準(zhǔn)入優(yōu)先級(jí);
5)上游接受到返回后解析信息,并更新本地記錄的下游服務(wù)準(zhǔn)入優(yōu)先級(jí)。
微信的整個(gè)過(guò)載控制策略有以下三個(gè)特點(diǎn):
1)業(yè)務(wù)無(wú)關(guān)的:使用請(qǐng)求等待時(shí)間而不是響應(yīng)時(shí)間,制定用戶和業(yè)務(wù)優(yōu)先級(jí),這些都與業(yè)務(wù)本身無(wú)關(guān);
2)高效且公平: 請(qǐng)求鏈條的優(yōu)先級(jí)是一致的,并且會(huì)定時(shí)改變 hash 函數(shù)調(diào)整用戶優(yōu)先級(jí),過(guò)載情況下,不會(huì)總是影響固定的用戶;
3)獨(dú)立控制和聯(lián)合控制結(jié)合:準(zhǔn)入優(yōu)先級(jí)取決于獨(dú)立的服務(wù),但又可以聯(lián)合下游服務(wù)的情況,優(yōu)化服務(wù)過(guò)載時(shí)的表現(xiàn)。
11、寫在最后
微信團(tuán)隊(duì)的分享只提到過(guò)載控制,但我相信服務(wù)調(diào)用方應(yīng)該還有一些其他機(jī)制,能夠解決不是因?yàn)橄掠畏?wù)過(guò)載,而是因?yàn)榫W(wǎng)絡(luò)抖動(dòng)導(dǎo)致的請(qǐng)求超時(shí)問(wèn)題。
微信的這套微服務(wù)過(guò)載控制機(jī)制(即DAGOR)提供的服務(wù)無(wú)關(guān)、去中心化、高效和公平等特性很好地在微信后端跑了很多年。
最后,微信團(tuán)隊(duì)還分享了他們?cè)O(shè)計(jì)和運(yùn)維DAGOR寶貴經(jīng)驗(yàn):
1)大規(guī)模微服務(wù)架構(gòu)中的過(guò)載控制必須在每個(gè)服務(wù)中實(shí)現(xiàn)分散和自治;
2)過(guò)載控制應(yīng)該要考慮到各種反饋機(jī)制(例如 DAGOR 的協(xié)作準(zhǔn)入控制),而不是僅僅依賴于開環(huán)啟發(fā)式;
3)應(yīng)該通過(guò)分析實(shí)際工作負(fù)載來(lái)了解過(guò)載控制設(shè)計(jì)。
12、參考資料
[1]?Overload Control for Scaling WeChat Microservices
[2]?羅神解讀“Overload Control for Scaling WeChat Microservices”
[3]?2W臺(tái)服務(wù)器、每秒數(shù)億請(qǐng)求,微信如何不“失控”?
[4]?DAGOR:微信微服務(wù)過(guò)載控制系統(tǒng)
[5]?月活 12.8 億的微信是如何防止崩潰的?
[6]?微信朋友圈千億訪問(wèn)量背后的技術(shù)挑戰(zhàn)和實(shí)踐總結(jié)
[7]?QQ 18年:解密8億月活的QQ后臺(tái)服務(wù)接口隔離技術(shù)
[8]?微信后臺(tái)基于時(shí)間序的海量數(shù)據(jù)冷熱分級(jí)架構(gòu)設(shè)計(jì)實(shí)踐
[9]?架構(gòu)之道:3個(gè)程序員成就微信朋友圈日均10億發(fā)布量[有視頻]》
[10]?快速裂變:見證微信強(qiáng)大后臺(tái)架構(gòu)從0到1的演進(jìn)歷程(一)
[11]?一份微信后臺(tái)技術(shù)架構(gòu)的總結(jié)性筆記》
13、論文原文
論文PDF請(qǐng)下載此附件:
(因無(wú)法上傳附件,請(qǐng)從此鏈接:http://www.52im.net/thread-3930-1-1.html文末的“參考資料”附件中下載)
論文PDF全部?jī)?nèi)容概覽:

(本文已同步發(fā)布于:http://www.52im.net/thread-3930-1-1.html)