聊聊架構(gòu)設(shè)計(jì)流程:識(shí)別復(fù)雜度
架構(gòu)設(shè)計(jì)第 1 步:識(shí)別復(fù)雜度
在設(shè)計(jì)軟件架構(gòu)的過(guò)程中,識(shí)別并理解系統(tǒng)的復(fù)雜性是至關(guān)重要的一步。這是因?yàn)?,只有?dāng)我們準(zhǔn)確地分析出系統(tǒng)面臨的主要復(fù)雜性時(shí),才能確保架構(gòu)設(shè)計(jì)方案的正確性。如果分析失誤,無(wú)論設(shè)計(jì)方案多么高級(jí),都可能偏離解決實(shí)際問(wèn)題的正確路徑,導(dǎo)致效果不佳。
考慮一個(gè)例子:假設(shè)一個(gè)系統(tǒng)主要的復(fù)雜性來(lái)源于其業(yè)務(wù)邏輯的復(fù)雜和功能之間的緊密耦合。如果在這種情況下,架構(gòu)師設(shè)計(jì)了一個(gè)以高吞吐量(TPS為50000/秒)為目標(biāo)的架構(gòu),那么無(wú)論這個(gè)架構(gòu)的性能表現(xiàn)有多優(yōu)秀,它都未能解決系統(tǒng)實(shí)際的復(fù)雜性問(wèn)題。
通常,架構(gòu)的復(fù)雜性源于需求對(duì)高性能、高可用性、可擴(kuò)展性等方面的要求。但在分析系統(tǒng)復(fù)雜性時(shí),架構(gòu)師不應(yīng)該機(jī)械地認(rèn)為所有系統(tǒng)都必須同時(shí)滿足這些要求。實(shí)際上,大多數(shù)情況下,復(fù)雜性問(wèn)題主要集中在上述幾個(gè)方面的某一個(gè)或某兩個(gè)方面。真正同時(shí)面臨三個(gè)或以上復(fù)雜性問(wèn)題的情況非常罕見(jiàn),這種情況通常意味著之前的系統(tǒng)設(shè)計(jì)存在問(wèn)題,或者是架構(gòu)師的分析判斷有誤。即便確實(shí)面對(duì)多重復(fù)雜性要求,也應(yīng)進(jìn)行優(yōu)先級(jí)排序,逐一解決。
以一個(gè)億級(jí)用戶平臺(tái)為例,該平臺(tái)最初的設(shè)計(jì)目標(biāo)是模仿騰訊QQ的用戶規(guī)模和功能復(fù)雜度,導(dǎo)致其設(shè)計(jì)了超過(guò)40個(gè)子系統(tǒng)。這種過(guò)度設(shè)計(jì)不僅導(dǎo)致系統(tǒng)過(guò)于復(fù)雜、運(yùn)維困難、開(kāi)發(fā)效率低下,而且由于業(yè)務(wù)并未達(dá)到預(yù)期的規(guī)模,造成了大量資源的浪費(fèi)。最終,團(tuán)隊(duì)不得不花費(fèi)額外的兩年時(shí)間進(jìn)行重構(gòu),將子系統(tǒng)數(shù)量減半,系統(tǒng)才逐漸趨于穩(wěn)定。
面對(duì)一個(gè)同時(shí)存在多個(gè)復(fù)雜度問(wèn)題的系統(tǒng),最合理的做法是分步驟解決。首先,明確系統(tǒng)面臨的主要復(fù)雜度問(wèn)題,并根據(jù)業(yè)務(wù)需求、技術(shù)現(xiàn)狀和團(tuán)隊(duì)能力進(jìn)行優(yōu)先級(jí)排序。例如,在上述億級(jí)用戶平臺(tái)的案例中,團(tuán)隊(duì)首先將精力集中在減少子系統(tǒng)數(shù)量上,這一改進(jìn)不僅提高了開(kāi)發(fā)效率,還減少了系統(tǒng)的故障率。在此基礎(chǔ)上,團(tuán)隊(duì)又成功實(shí)施了異地多活方案,進(jìn)一步提升了系統(tǒng)的穩(wěn)定性。
擔(dān)心按優(yōu)先級(jí)解決問(wèn)題可能導(dǎo)致后續(xù)需推倒重來(lái)的方案是有理論基礎(chǔ)的,但在實(shí)踐中幾乎不會(huì)發(fā)生。軟件系統(tǒng)的可塑性和靈活性意味著對(duì)于同一問(wèn)題,通常存在多種解決方案。即使真的需要重構(gòu),新方案也應(yīng)該能夠同時(shí)解決之前已解決的問(wèn)題,而這通常依賴于新技術(shù)的引入。比如,Hadoop就是一個(gè)能夠同時(shí)處理大數(shù)據(jù)的高性能、高可用性和大容量問(wèn)題的技術(shù)解決方案。
對(duì)架構(gòu)師而言,識(shí)別系統(tǒng)復(fù)雜性是一項(xiàng)挑戰(zhàn),需要在深入理解需求的基礎(chǔ)上進(jìn)行全面分析。有經(jīng)驗(yàn)的架構(gòu)師可能能迅速洞察復(fù)雜性所在,而對(duì)于經(jīng)驗(yàn)較少的架構(gòu)師,則可能需要通過(guò)排查法,從不同角度逐一分析,才能準(zhǔn)確把握系統(tǒng)的復(fù)雜性。
圖片
識(shí)別復(fù)雜度實(shí)戰(zhàn)
在創(chuàng)業(yè)公司“前浪微博(虛擬)”的快速發(fā)展過(guò)程中,其系統(tǒng)架構(gòu)開(kāi)始顯現(xiàn)出效率低下的問(wèn)題,尤其是在多個(gè)業(yè)務(wù)子系統(tǒng)間的協(xié)作上。以發(fā)布微博為例,從審核到統(tǒng)計(jì)、廣告預(yù)測(cè)再到消息推送,微博子系統(tǒng)需要與十幾個(gè)其他系統(tǒng)進(jìn)行接口調(diào)用,每增加一個(gè)通知,就意味著額外的接口設(shè)計(jì)和測(cè)試工作,這大大降低了開(kāi)發(fā)效率,同時(shí)使問(wèn)題定位變得異常復(fù)雜。同樣的情況也出現(xiàn)在用戶升級(jí)至VIP等級(jí)時(shí),等級(jí)子系統(tǒng)需要通知諸如福利、客服、商品子系統(tǒng)等多個(gè)系統(tǒng)進(jìn)行相應(yīng)處理。
針對(duì)這些挑戰(zhàn),一位新加入的架構(gòu)師提出引入消息隊(duì)列系統(tǒng)來(lái)解耦各個(gè)子系統(tǒng)的直接依賴。經(jīng)過(guò)一系列的分析、討論和審批后,該提案得到了批準(zhǔn)。
在對(duì)消息隊(duì)列系統(tǒng)的需求進(jìn)行深入分析時(shí),中間件團(tuán)隊(duì)采用了“排查法”來(lái)確定其面臨的主要復(fù)雜性。首先關(guān)注的是性能問(wèn)題。假設(shè)前浪微博每天產(chǎn)生1000萬(wàn)條微博消息,每條微博消息需被十個(gè)子系統(tǒng)處理,這意味著日總消息處理量約為1億次。將這個(gè)數(shù)字分解到每秒,意味著平均每秒需處理115條寫(xiě)入消息和1150條讀取消息。但為了應(yīng)對(duì)峰值,設(shè)計(jì)目標(biāo)通常設(shè)定為平均值的三倍,即TPS(每秒事務(wù)處理量)為345,QPS(每秒查詢處理量)為3450。即使如此,考慮到業(yè)務(wù)增長(zhǎng),性能設(shè)計(jì)目標(biāo)被進(jìn)一步設(shè)定為峰值的四倍,即TPS為1380,QPS為13800,以保證系統(tǒng)對(duì)未來(lái)業(yè)務(wù)增長(zhǎng)的充分準(zhǔn)備。
接下來(lái)是高可用性的需求分析。考慮到消息丟失可能帶來(lái)的嚴(yán)重后果,如審核系統(tǒng)的消息丟失可能導(dǎo)致違反法規(guī),VIP等級(jí)獎(jiǎng)勵(lì)的不發(fā)放可能導(dǎo)致用戶不滿,消息隊(duì)列在寫(xiě)入、存儲(chǔ)和讀取各環(huán)節(jié)都需保證高度的可靠性。
至于可擴(kuò)展性,鑒于消息隊(duì)列的功能較為固定,當(dāng)前看來(lái)并不是主要的復(fù)雜度所在。
綜合上述分析,消息隊(duì)列系統(tǒng)面臨的主要復(fù)雜性在于高性能的消息讀取和全流程的高可用性保障。這次詳細(xì)的分析和討論,不僅適用于“前浪微博”面臨的挑戰(zhàn),也為其他企業(yè)提供了一種系統(tǒng)性問(wèn)題解決的框架。需要注意的是,這里的性能目標(biāo)設(shè)定為峰值的四倍主要是基于對(duì)業(yè)務(wù)增長(zhǎng)速度的預(yù)估,并不是一個(gè)固定的倍數(shù),不同業(yè)務(wù)場(chǎng)景下的預(yù)估倍數(shù)可能會(huì)有所不同。