高并發(fā)代表著高流量,高并發(fā)系統(tǒng)的魅力就在于我們可用憑借自己的聰明才智設(shè)計(jì)巧妙的方案,從而抵抗住流量的沖擊,帶給用戶更好的使用體驗(yàn)。讓流量可以平穩(wěn)的被系統(tǒng)中服務(wù)和組件進(jìn)行處理。
而我們?cè)趹?yīng)對(duì)高并發(fā)大流量時(shí)也會(huì)采用類(lèi)似“抵御洪水”的方案,歸納起來(lái)共有三種方法。
- Scale-out(橫向擴(kuò)展): 分而治之是一種常見(jiàn)的高并發(fā)系統(tǒng)設(shè)計(jì)方法,采用分布式部署的方式把流量分流開(kāi),讓每個(gè)服務(wù)器都承擔(dān)一部分并發(fā)和流量
- 緩存:使用緩存來(lái)提高系統(tǒng)性能,就好比用“拓寬河道”的方式抵抗高并發(fā)大流量的沖擊。
- 異步: 在某些場(chǎng)景下,未處理完成之前我們可以讓請(qǐng)求先返回,在數(shù)據(jù)準(zhǔn)備好之后,再通知請(qǐng)求方,這樣可以在單位時(shí)間處理更多的請(qǐng)求。
異步調(diào)用在大規(guī)模高并發(fā)系統(tǒng)中被大量使用,比如我們熟知的 12306 網(wǎng)站。 當(dāng)我們訂票時(shí),頁(yè)面會(huì)顯示系統(tǒng)正在排隊(duì),這個(gè)提示就代表著系統(tǒng)在異步處理我們的訂票請(qǐng)求。 在 12306 系統(tǒng)中查詢余票、下單和更改余票狀態(tài)都是比較耗時(shí)的操作,可能涉及多個(gè)內(nèi)部系統(tǒng)的互相調(diào)用,如果是同步調(diào)用就會(huì)像 12306 剛剛上線時(shí)那樣,高峰期永遠(yuǎn)不可能下單成功。
而采用異步的方式,后端處理時(shí)會(huì)把請(qǐng)求丟到消息隊(duì)列中,同時(shí)快速響應(yīng)用戶,告訴用戶我們正在排隊(duì)處理,然后釋放出資源來(lái)處理更多的請(qǐng)求。訂票請(qǐng)求處理完之后,再通知用戶訂票成功或者失敗。
處理邏輯后移到異步處理程序中,Web 服務(wù)的壓力小了,資源占用的少了,自然就能接收更多的用戶訂票請(qǐng)求,系統(tǒng)承受高并發(fā)的能力也就提升了。

既然我們了解了這三種方法,那么是不是意味著在高并發(fā)系統(tǒng)設(shè)計(jì)中,開(kāi)發(fā)一個(gè)系統(tǒng)時(shí)要把這些方法都用上呢?當(dāng)然不是,系統(tǒng)的設(shè)計(jì)是不斷演進(jìn)的。
羅馬不是一天建成的,系統(tǒng)的設(shè)計(jì)也是如此。不同量級(jí)的系統(tǒng)有不同的痛點(diǎn),也就有不同的架構(gòu)設(shè)計(jì)的側(cè)重點(diǎn)。如果都按照百萬(wàn)、千萬(wàn)并發(fā)來(lái)設(shè)計(jì)系統(tǒng),電商一律向淘寶看齊,IM 全都學(xué)習(xí)微信和 QQ,那么這些系統(tǒng)的命運(yùn)一定是滅亡。
我之前也踩過(guò)一些坑,參與的一個(gè)創(chuàng)業(yè)項(xiàng)目,在初始階段就采用了微服務(wù)化架構(gòu),但由于當(dāng)時(shí)人力有限,團(tuán)隊(duì)技術(shù)積累不足,因此在實(shí)際項(xiàng)目開(kāi)發(fā)中,發(fā)現(xiàn)無(wú)法駕馭如此復(fù)雜的架構(gòu),出現(xiàn)問(wèn)題,難以定位,系統(tǒng)整體性能下降等多方面的問(wèn)題,設(shè)置系統(tǒng)宕機(jī)了都無(wú)法查到哪方面的原因,最后不得不回歸到簡(jiǎn)體的架構(gòu)中。
所以我的建議:
- 滿足業(yè)務(wù)需求和流量現(xiàn)狀,選擇最簡(jiǎn)單的系統(tǒng)設(shè)計(jì)和技術(shù)體系
- 隨著業(yè)務(wù)的增加和流量的變化,逐步修正系統(tǒng)中存在的問(wèn)題,比如單點(diǎn)問(wèn)題、橫向擴(kuò)展問(wèn)題,遇到瓶頸的組件等,盡量選擇有開(kāi)源社區(qū)支持的組件,社區(qū)實(shí)在沒(méi)有解決方案的前提下,才會(huì)自己造輪子。
- 當(dāng)對(duì)架構(gòu)的小修小補(bǔ)無(wú)法滿足需求時(shí),考慮重構(gòu)、重寫(xiě)等調(diào)整方式以解決現(xiàn)有問(wèn)題。
以淘寶為例,當(dāng)時(shí)在業(yè)務(wù)從 0 到 1 的階段是通過(guò)購(gòu)買(mǎi)的方式快速搭建了系統(tǒng)。而后,隨著流量的增長(zhǎng),淘寶做了一系列的技術(shù)改造來(lái)提升高并發(fā)處理能力,比如數(shù)據(jù)庫(kù)存儲(chǔ)引擎從 MyISAM 遷移到 InnoDB,數(shù)據(jù)庫(kù)做分庫(kù)分表,增加緩存,啟動(dòng)中間件研發(fā)等。
當(dāng)這些都無(wú)法滿足時(shí),就考慮整體架構(gòu)的大規(guī)模重構(gòu),比如著名的五彩石”項(xiàng)目讓淘寶的架構(gòu)從單體演進(jìn)為服務(wù)化架構(gòu)。 正是通過(guò)逐步的技術(shù)演進(jìn),淘寶才進(jìn)化出如今承擔(dān)過(guò)億 QPS 的技術(shù)架構(gòu)。
總結(jié)
歸根揭底一句話:高并發(fā)系統(tǒng)的演進(jìn)應(yīng)該時(shí)循序漸進(jìn)的,以解決實(shí)際業(yè)務(wù)中問(wèn)題為目的和驅(qū)動(dòng)力的。
本節(jié)主要介紹三種高并發(fā)系統(tǒng)設(shè)計(jì)的思路:scale-out、緩存、異步。
至于具體采取哪一種方式,還是全部都采用還要跟進(jìn)你自己系統(tǒng)來(lái)考量。
高并發(fā)系統(tǒng)是一個(gè)漸進(jìn)的過(guò)程,并非一蹴而就:
martin fowler 說(shuō)過(guò),能用單體解決的問(wèn)題,就不用分布式。不能為了技術(shù)而技術(shù),采用分布式固然可以分流用戶請(qǐng)求,提高系統(tǒng)的響應(yīng)能力,但同樣也帶來(lái)了復(fù)雜性。如果單體能解決的問(wèn)題,就不要想著詩(shī)和遠(yuǎn)方,因?yàn)橄到y(tǒng)內(nèi)部進(jìn)程間的調(diào)用,肯定比不同物理機(jī)的進(jìn)程之間調(diào)用的更快。
高并發(fā)除了橫向擴(kuò)容,緩存和異步化,系統(tǒng)還要做好保護(hù),比如限流降級(jí),過(guò)載保護(hù)。