混!架構(gòu)師必備理論和基礎
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質(zhì)文章,第一時間送達
什么是架構(gòu)?架構(gòu)的發(fā)展歷程
一.背景
?在我們的工作中,時常伴隨的架構(gòu)一詞,如:MVC架構(gòu)、微信架構(gòu)、淘寶架構(gòu)…,雖然常見,但具體的指的是什么呢?
架構(gòu)和框架是什么關系?有什么區(qū)別?
Linux 有架構(gòu),MySQL 有架構(gòu),JVM 也有架構(gòu),使用 Java 開發(fā)、MySQL 存儲、跑在 Linux 上的業(yè)務系統(tǒng)也有架構(gòu),應該關注哪個架構(gòu)呢?
微信有架構(gòu),微信的登錄系統(tǒng)也有架構(gòu),微信的支付系統(tǒng)也有架構(gòu),當我們談微信架構(gòu)時,到底是在談什么架構(gòu)?
?要想準確地回答這些問題,關鍵在于一些似是而非的概念,如:系統(tǒng)與子系統(tǒng)、模塊與組件、框架與架構(gòu)。
1.系統(tǒng)與子系統(tǒng)
?維基百科對系統(tǒng)的定義為:
系統(tǒng)泛指由一群有關聯(lián)的個體組成,根據(jù)某種規(guī)則運作,能完成個別元件不能單獨完成的工作的群體。它的意思是“總體”“整體”或“聯(lián)盟”。
?在這段描述中可知,系統(tǒng)的主要關鍵點可以提煉為關聯(lián)(個體之間是有一定的關聯(lián)關系的),規(guī)則(個體之間需要按照某種骨規(guī)則運行),能力(系統(tǒng)能力和個體能力會有本質(zhì)的區(qū)別,不是簡單的 1+1 的關系)。
?維基百科對子系統(tǒng)的定義為:
子系統(tǒng)也是由一群有關聯(lián)的個體所組成的系統(tǒng),多半會是更大系統(tǒng)中的一部分。
?其實子系統(tǒng)和系統(tǒng)的定義沒有什么差別,只是觀察的角度不一樣,一個系統(tǒng)可能會是另一個更大系統(tǒng)的子系統(tǒng)。以微信系統(tǒng)做分析:
微信本身是一個系統(tǒng),包含聊天、登錄、支付、朋友圈等子系統(tǒng)。
朋友圈這個系統(tǒng)又包括動態(tài)、評論、點贊等子系統(tǒng)。
評論這個系統(tǒng)可能又包括防刷子系統(tǒng)、審核子系統(tǒng)、發(fā)布子系統(tǒng)、存儲子系統(tǒng)。
評論審核子系統(tǒng)不再包含業(yè)務意義上的子系統(tǒng),而是包括各個模塊或者組件,這些模塊或者組件本身也是另外一個維度上的系統(tǒng)。例如,MySQL、Redis 等是存儲系統(tǒng),但不是業(yè)務子系統(tǒng)。
2.模塊與組件
?模塊和組件是很容易讓人混淆的兩個名詞,如:Mysql 模塊只要負責數(shù)據(jù)的存儲;XX項目有安全加密組件、審核組件,某某 App 的下載模塊使用了第三方的組件等描述。模塊和組件的定義如下:
?維基百科對模塊的定義為:
軟件模塊(Module)是一套一致而互相有緊密關連的軟件組織。它分別包含了程序和數(shù)據(jù)結(jié)構(gòu)兩部分?,F(xiàn)代軟件開發(fā)往往利用模塊作為合成的單位。模塊的接口表達了由該模塊提供的功能和調(diào)用它時所需的元素。模塊是可能分開被編寫的單位。這使它們可再用和允許人員同時協(xié)作、編寫及研究不同的模塊。
?維基百科對組件的定義為:
軟件組件定義為自包含的、可編程的、可重用的、與語言無關的軟件單元,軟件組件可以很容易被用于組裝應用程序中。
?從兩者的定義來看,其實沒有太大的差異,主要原因是:因為模塊和組件都是一個系統(tǒng)的組成部分,只不過是從不同的角度進行拆分。
?如果我們從邏輯的角度對系統(tǒng)進行拆分,得到的就是“模塊”;如果我們從物理的角度對系統(tǒng)進行拆分,得到的就是“組件”。而劃分模塊的主要目的是職責分離;劃分組件的主要目的是單元復用。其實組件的定義,更類似于我們生活中的“零件”一詞。
3.框架與架構(gòu)
?框架和架構(gòu)也是一個比較相似的概念,并且這兩者在工作上有較強的關聯(lián)關系,其定義如下:
?維基百科對框架的定義為:
軟件框架(Software framework)通常指的是為了實現(xiàn)某個業(yè)界標準或完成特定基本任務的軟件組件規(guī)范,也指為了實現(xiàn)某個軟件組件規(guī)范時,提供規(guī)范所要求之基礎功能的軟件產(chǎn)品。
?從定義中可看出,對于框架一詞,主要的描述為框架是組件規(guī)范(如 MVC 開發(fā)規(guī)范)、框架是提供基礎功能的產(chǎn)品(如 Spring MVC框架、Spring 框架等,提供了一下基礎功能,簡易了開發(fā))。
?維基百科對架構(gòu)的定義為:
軟件架構(gòu)指軟件系統(tǒng)的“基礎結(jié)構(gòu)”,創(chuàng)造這些基礎結(jié)構(gòu)的準則,以及對這些結(jié)構(gòu)的描述。
?從兩者定義的角度看,框架和架構(gòu)的關注點是不一樣的,框架關注的是規(guī)范;而架構(gòu)關注的是結(jié)構(gòu),但是對于這個基礎結(jié)構(gòu),并沒有明確的說明是從哪個角度進行分解的,所以也就有了 IBM 的 RUP 將軟件架構(gòu)視圖分為著名的“4+1 視圖”。
4.4 + 1 視圖:學生管理系統(tǒng)分析
?在實際工作中我們卻經(jīng)常碰到一些似是而非的說法。例如,“我們的系統(tǒng)是 MVC 架構(gòu)”“我們需要將 android app 重構(gòu)為 MVP 架構(gòu)”“我們的系統(tǒng)基于 SSH 框架開發(fā)”“我們是 SSH 的架構(gòu)”“XX 系統(tǒng)是基于 Spring MVC 框架開發(fā),標準的 MVC 架構(gòu)”……
?究竟什么說法是對的,什么說法是錯的呢?
?其實這些說法都是對的,造成這種現(xiàn)象的根本原因隱藏于架構(gòu)的定義中,關鍵就是“基礎結(jié)構(gòu)”這個概念并沒有明確說是從什么角度來分解的。
?假設我們要做一個學生信息管理系統(tǒng),這個系統(tǒng)從邏輯的角度來拆分,可以分為“登錄注冊模塊”“個人信息模塊”“個人成績模塊”;從物理的角度來拆分,可以拆分為 Nginx、Web 服務器、MySQL。
?從業(yè)務邏輯的角度分解,“學生管理系統(tǒng)”的架構(gòu)是:
?從物理部署的角度分解,“學生管理系統(tǒng)”的架構(gòu)是:
?從開發(fā)規(guī)范的角度分解,“學生管理系統(tǒng)”可以采用標準的 MVC 框架來開發(fā),因此架構(gòu)又變成了 MVC 架構(gòu):
“4+1”視圖模型
?“4+1”視圖模型是從5個不同的視角去描述軟件的體系結(jié)構(gòu),這些視圖包括:邏輯視圖、進程視圖、物理視圖、開發(fā)視圖和場景視圖。
?每一個視圖只關心系統(tǒng)的一個側(cè)面,5個視圖結(jié)合在一起才能反映系統(tǒng)的軟件體系結(jié)構(gòu)的全部內(nèi)容(架構(gòu))。
5.重新定義架構(gòu)
?參考維基百科的定義,可以將架構(gòu)重新定義為:軟件架構(gòu)指軟件系統(tǒng)的頂層結(jié)構(gòu)。
?這個定義看似比較簡單,但包含的信息卻很豐富,基本上把系統(tǒng)、子系統(tǒng)、模塊、組件、架構(gòu)等概念都串起來了。
首先,“系統(tǒng)是一群關聯(lián)個體組成”,這些“個體”可以是“子系統(tǒng)”“模塊”“組件”等;架構(gòu)需要明確系統(tǒng)包含哪些“個體”。
其次,系統(tǒng)中的個體需要“根據(jù)某種規(guī)則”運作,架構(gòu)需要明確個體運作和協(xié)作的規(guī)則。
最后,維基百科定義的架構(gòu)用到了“基礎結(jié)構(gòu)”這個說法,這里改為“頂層結(jié)構(gòu)”,可以更好地區(qū)分系統(tǒng)和子系統(tǒng),避免將系統(tǒng)架構(gòu)和子系統(tǒng)架構(gòu)混淆在一起導致架構(gòu)層次混亂。
6.架構(gòu)的發(fā)展史
?要想深入理解一個事物的本質(zhì),最好的方式就是去追尋這個事物出現(xiàn)的歷史背景和推動因素。
(1)機器語言(1940 年之前)
?使用二進制的形式,其主要的問題是:太難寫、太難讀、太難改!
(2)匯編語言(20 世紀 40 年代)
?匯編語言又叫“符號語言”,用助記符代替機器指令的操作碼,用地址符號(Symbol)或標號(Label)代替指令或操作數(shù)的地址。
?解決了機器語言讀寫復雜的問題,但是本質(zhì)上還是面向機器的,因此,需要去了解計算機很多底層知識(CPU、寄存器等);同時,不同 CPU 的匯編指令和結(jié)構(gòu)還不一樣。
(3)高級語言(20 世紀 50 年代)
?稱為高級語言是因為不需要程序員去關注計算機底層的知識,只需要關注自己的業(yè)務即可;同時,通過編譯器的處理,能將其編譯成適合不同 CPU 指令的機器語言。
(4)第一次軟件危機與結(jié)構(gòu)化程序設計(20 世紀 60 年代~20 世紀 70 年代)
?“1963 年美國(http://en.wikipedia.org/wiki/Mariner_1)的水手一號火箭發(fā)射失敗事故”,“IBM 的 System/360 的操作系統(tǒng)開發(fā)事故”等事故,創(chuàng)造了“軟件危機”一詞,為了解決軟件危機問題,分別提出了解決方案:
1968、1969 提出“軟件工程”方案
1968 年“結(jié)構(gòu)化程序設計”方案
結(jié)構(gòu)化程序設計的主要特點是拋棄 goto 語句,采取“自頂向下、逐步細化、模塊化”的指導思想。結(jié)構(gòu)化程序設計本質(zhì)上還是一種面向過程的設計思想,但通過“自頂向下、逐步細化、模塊化”的方法,將軟件的復雜度控制在一定范圍內(nèi),從而從整體上降低了軟件開發(fā)的復雜度。結(jié)構(gòu)化程序方法成為了 20 世紀 70 年代軟件開發(fā)的潮流。
(5)第二次軟件危機與面向?qū)ο螅?0 世紀 80 年代)
?第二次軟件危機的根本原因還是在于軟件生產(chǎn)力遠遠跟不上硬件和業(yè)務的發(fā)展。第一次軟件危機的根源在于軟件的“邏輯”變得非常復雜,而第二次軟件危機主要體現(xiàn)在軟件的“擴展”變得非常復雜。結(jié)構(gòu)化程序設計雖然能夠解決(也許用“緩解”更合適)軟件邏輯的復雜性,但是對于業(yè)務變化帶來的軟件擴展卻無能為力,軟件領域迫切希望找到新的銀彈來解決軟件危機,在這種背景下,面向?qū)ο蟮乃枷腴_始流行起來。
雖然面向?qū)ο箝_始也被當作解決軟件危機的銀彈,但事實證明,和軟件工程一樣,面向?qū)ο笠膊皇倾y彈,而只是一種新的軟件方法而已。
(6)軟件架構(gòu)
?軟件架構(gòu)的出現(xiàn),并不是整個行業(yè)面臨了類似的問題,也不是為了解決新的軟件危機。而是當時某些企業(yè)發(fā)展到一定程度后,為了解決面臨的軟件問題,而被提出。如:Rational 或者 Microsoft 這樣的大公司。
?軟件架構(gòu)的出現(xiàn)有其歷史必然性。20 世紀 60 年代第一次軟件危機引出了“結(jié)構(gòu)化編程”,創(chuàng)造了“模塊”概念;20 世紀 80 年代第二次軟件危機引出了“面向?qū)ο缶幊獭?/span>,創(chuàng)造了“對象”概念;到了 20 世紀 90 年代“軟件架構(gòu)”開始流行,創(chuàng)造了“組件”概念。我們可以看到,“模塊”“對象”“組件”本質(zhì)上都是對達到一定規(guī)模的軟件進行拆分,差別只是在于隨著軟件的復雜度不斷增加,拆分的粒度越來越粗,拆分的層次越來越高。
為什么要有架構(gòu)?架構(gòu)解決了一些什么問題?
架構(gòu)設計貌似是一個高大上的名詞,但是如果深入思考一下,“為何要做架構(gòu)設計?”或者“架構(gòu)設計目的是什么?”,還有可信的答案嗎?
一.目的
1.誤區(qū)
?談到為什么需要架構(gòu)這個話題,不同的人有著不同的理解,如:
因為架構(gòu)很重要,所以要做架構(gòu)設計
不是每個系統(tǒng)都要做架構(gòu)設計嗎?
公司流程要求系統(tǒng)開發(fā)過程中必須有架構(gòu)設計
為了高性能、高可用、可擴展,所以要做架構(gòu)設計
?這些說法都有一定的理由,但本質(zhì)上都是為了架構(gòu)而架構(gòu),沒有結(jié)合具體的業(yè)務場景,而是將其當做一種所謂的銀彈。
2.架構(gòu)設計的目的
?通過上一篇文章,我們知道,架構(gòu)的提出,是為了應對是為了應對軟件系統(tǒng)復雜度(邏輯、擴展等)而提出的一個解決方案,其目主要是為了:解決軟件系統(tǒng)復雜度帶來的問題。
?那么我們在做系統(tǒng)設計的時候,首先就是要分析系統(tǒng)復雜度的來源,做到心中有數(shù),而不是一片霧水;分析清楚復雜度后,接下來就是設計,來解決系統(tǒng)中的復雜度,在這個過程中,切勿貪大求全,而要有的放矢,畢竟,羅馬不是一日建成的。
?進行系統(tǒng)復雜度分析的一些維度:性能、可擴展性、高可用、安全性、成本等。
二.解決的問題
?既然架構(gòu)設計的主要問題就是分析系統(tǒng)得到復雜度,那么,這些復雜度主要包括哪些呢?
1.高性能
?性能的提升,一定會帶來復雜度的提升嗎?并不一定,如:硬件存儲從紙帶→磁帶→磁盤→SSD,并沒有顯著帶來系統(tǒng)復雜度的增加。因為新技術會逐步淘汰舊技術,這種情況下我們直接用新技術即可,不用擔心系統(tǒng)復雜度會隨之提升。只有那些并不是用來取代舊技術,而是開辟了一個全新領域的技術,才會給軟件系統(tǒng)帶來復雜度,因為軟件系統(tǒng)在設計的時候就需要在這些技術之間進行判斷選擇或者組合。
?單臺計算機內(nèi)部為了高性能帶來的復雜度
單機性能的提升:手工操作 》批處理操作系統(tǒng)》進程》線程
帶來的復雜度:進程/線程間的通信方式(管道、消息隊列、信號量、共享存儲)、多核處理器架構(gòu)
示例:Redis 采用的是單進程、Memcache 采用的是多線程、Nginx 可以用多進程也可以用多線程
?多臺計算機集群為了高性能帶來的復雜度
集群性能的提升:任務分配(使用多臺機器來分擔運行)、任務分解(對任務的拆分,如:多機器協(xié)調(diào)或者服務拆分)
任務分配的復雜度:需要任務分配器(Nginx、F5)、連接管理、分配算法(輪詢)
任務分解的復雜度:不同任務間的通信、任務的拆分
?集群性能計算:
假設單臺業(yè)務服務器每秒能夠處理 5000 次業(yè)務請求,那么兩臺業(yè)務服務器理論上能夠支撐 10000 次請求,實際上的性能一般按照 8 折計算,大約是 8000 次左右。
2.高可用
?維基百科對高可用的定義為:
系統(tǒng)無中斷地執(zhí)行其功能的能力,代表系統(tǒng)的可用性程度,是進行系統(tǒng)設計時的準則之一。
?但是,無論是單個硬件還是單個軟件,都不可能做到無中斷,硬件會出故障,軟件會有 bug;硬件會逐漸老化,軟件會越來越復雜和龐大……,所以,硬件和軟件本質(zhì)上無法做到“無中斷”。
?各種高可用的方案,其實本質(zhì)上都是一種冗余(單個機器保證不了),也就是通過添加機器的方式來實現(xiàn),這和高性能的方式一樣,但是,兩者的目的有所不同:高性能增加機器目的在于“擴展”處理性能;高可用增加機器目的在于“冗余”處理單元。
?在高可用體系中,根據(jù)其特性,可以簡單的將其分為計算高可用,和存儲高可用。
?計算高可用:
特點:無論在哪臺機器上進行計算,同樣的算法和輸入數(shù)據(jù),產(chǎn)出的結(jié)果都是一樣的。
復雜度:需要任務分配器(Nginx、F5)、連接管理、分配算法(雙機算法:主備<冷備、溫備、熱備>、主主)
示例:ZooKeeper 采用的就是 1 主多備、Memcached 采用的就是全主 0 備
?存儲高可用:
特點:將數(shù)據(jù)從一臺機器搬到到另一臺機器,需要經(jīng)過線路進行傳輸。
復雜度:如何進行數(shù)據(jù)的備份、如何減少或者規(guī)避數(shù)據(jù)不一致
?數(shù)據(jù)在備份的過程中,有物理上的傳輸速度限制(光纖、帶寬)、也有傳輸線路本身的問題(中斷、擁塞、異常<錯包、丟包>)。但是無論是正常情況下的傳輸延遲,還是異常情況下的傳輸中斷,都會導致系統(tǒng)的數(shù)據(jù)在某個時間點或者時間段是不一致的,而數(shù)據(jù)的不一致又會導致業(yè)務問題;但如果完全不做冗余,系統(tǒng)的整體高可用又無法保證,所以存儲高可用的難點不在于如何備份數(shù)據(jù),而在于如何減少或者規(guī)避數(shù)據(jù)不一致對業(yè)務造成的影響。
?狀態(tài)的決策:
?無論是計算高可用還是存儲高可用,其基礎都是“狀態(tài)決策”,即系統(tǒng)需要能夠判斷當前的狀態(tài)是正常還是異常,如果出現(xiàn)了異常就要采取行動來保證高可用。但是由于高可用的本質(zhì)是“冗余”,而數(shù)據(jù)的冗余又依賴于數(shù)據(jù)的備份(數(shù)據(jù)的傳輸),所以,高可用體系中的狀態(tài)決策不可能做到完全正確。創(chuàng)建的狀態(tài)決策方式有以下幾種:
?(1)獨裁式
指的是存在一個獨立的決策主體,來收集信息,然后進行決策。其問題在于“決策者”本身怎么去解決單點問題。
?(2)協(xié)商式
指的是兩個獨立的個體通過交流信息,然后根據(jù)規(guī)則進行決策,如:主備決策。其難點在于信息交換的時候出現(xiàn)了問題(比如主備連接中斷),此時狀態(tài)決策應該怎么做?
?(3)民主式
指的是多個獨立的個體通過投票的方式來進行狀態(tài)決策。和協(xié)商式類似,其基礎都依賴于獨立的個體之間交換信息。但是,民主式?jīng)Q策更加復雜,可以看成是對協(xié)商式的一種升級版本。這種決策方式在集群中可能會出現(xiàn)“腦裂”現(xiàn)象,其解決辦法是采用【節(jié)點奇數(shù)個數(shù) + 過半原則來解決】。但是,這種處理辦法,會降低了系統(tǒng)整體的可用性(不是腦裂,而是節(jié)點故障)。
示例:ZooKeeper 集群在選舉 leader 時就是采用這種方式。
?綜合上述的分析,無論采取什么樣的方案,狀態(tài)決策都不可能做到任何場景下都沒有問題。高可用的解決方法不是解決,而是減少或者規(guī)避,而規(guī)避某個問題的時候,一般都會引發(fā)另一個問題,只是這個問題比之前的小,高可用的設計過程本質(zhì)上就是一個取舍的過程。這也就是為什么系統(tǒng)可用性永遠只是說幾個九,永遠缺少那個一。
3.可擴展
?可擴展性指系統(tǒng)為了應對將來需求變化而提供的一種擴展能力,當有新的需求出現(xiàn)時,系統(tǒng)不需要或者僅需要少量修改就可以支持,無須整個系統(tǒng)重構(gòu)或者重建。
?設計具備良好可擴展性的系統(tǒng),有兩個基本條件:正確預測變化、完美封裝變化。
?正確預測變化:
根據(jù)經(jīng)驗,去進行一些需求的預測,但是如何把握預測的程度和提升預測結(jié)果的準確性,是一件很復雜的事情,而且沒有通用的標準可以簡單套上去,更多是靠自己的經(jīng)驗、直覺。
?完美封裝變化:常用的方式主要有兩種
第一種:將“變化”封裝在一個“變化層”,將不變的部分封裝在一個獨立的“穩(wěn)定層”:
需要去分析,哪些是不變層,哪些是穩(wěn)定層?對于變化層來說,還要在有差異的多個實現(xiàn)方式中找出共同點,并且保證在有新功能添加的時候,接口設計不會做太大的修改。
第二種:提煉出一個“抽象層”和一個“實現(xiàn)層”
抽象層是穩(wěn)定的,實現(xiàn)層可以根據(jù)具體業(yè)務需要定制開發(fā)。
4.低成本
?當我們設計“高性能”“高可用”的架構(gòu)時,通用的手段都是增加更多服務器來滿足“高性能”和“高可用”的要求;而低成本恰恰與此相反,我們需要減少服務器的數(shù)量才能達成低成本的目標。因此,低成本本質(zhì)上是與高性能和高可用沖突的,所以低成本很多時候不會是架構(gòu)設計的首要目標,而是架構(gòu)設計的附加約束。
?也就是說,我們首先需要設定一個成本目標,當我們根據(jù)高性能、高可用的要求設計出方案時,評估一下方案是否能滿足成本目標,如果不行,就需要重新設計架構(gòu);如果無論如何都無法設計出滿足成本要求的方案,那就只能找老板調(diào)整成本目標了。
?低成本給架構(gòu)設計帶來的主要復雜度體現(xiàn)在,往往只有“創(chuàng)新”才能達到低成本目標。這里的“創(chuàng)新”既包括開創(chuàng)一個全新的技術領域(開創(chuàng)新技術),也包括引入新技術,如果沒有找到能夠解決自己問題的新技術,那么就真的需要自己創(chuàng)造新技術了。
5.安全
?從技術的角度來講,安全可以分為兩類:一類是功能上的安全,一類是架構(gòu)上的安全。
?功能安全:
如常見的 XSS 攻擊、CSRF 攻擊、SQL 注入、Windows 漏洞、密碼破解等,其本質(zhì)上是因為系統(tǒng)實現(xiàn)有漏洞,黑客有了可乘之機。
從實現(xiàn)上來看,功能安全更多地是和具體的編碼相關,與架構(gòu)關系不大。并且,這類安全問題,是無法完全進行預測的,更多的是在問題出現(xiàn)后,針對性的處理,然后不斷完善系統(tǒng)安全的一個過程。
功能安全其實也是一個“攻”與“防”的矛盾,只能在這種攻防大戰(zhàn)中逐步完善,不可能在系統(tǒng)架構(gòu)設計的時候一勞永逸地解決。
?架構(gòu)安全:
在互聯(lián)網(wǎng)時代,理論上來說只要系統(tǒng)部署在互聯(lián)網(wǎng)上,全球任何地方都可以發(fā)起攻擊。
防火墻:
主要運用在傳統(tǒng)的架構(gòu)安全中,如:銀行,其成本較高,性能一般,并且在面對一些攻擊時(DDos 攻擊),其效果并不是很好。
依靠運營商或者云服務商強大的帶寬和流量清洗的能力:
互聯(lián)網(wǎng)常用的手段,很少自己來設計實現(xiàn)。
6.規(guī)模
?規(guī)模帶來復雜度的主要原因就是“量變引起質(zhì)變”,當數(shù)量超過一定的閾值后,復雜度會發(fā)生質(zhì)的變化。常見的規(guī)模帶來的復雜度有:
功能越來越多,導致系統(tǒng)復雜度指數(shù)級上升
一個系統(tǒng),包含了太多的功能需求,各個功能點之間相互依賴耦合。
數(shù)據(jù)越來越多,系統(tǒng)復雜度發(fā)生質(zhì)變
系統(tǒng)數(shù)據(jù)越來越多時,也會由量變帶來質(zhì)變。如:MySQL 單表數(shù)據(jù)超過 5000 萬、10 億等。
架構(gòu)原則,架構(gòu)設計需要注意哪些問題?
一.設計原則
?架構(gòu)設計我我們平時寫代碼不一樣,兩者的差異主要體現(xiàn)在“不確定性”上。對于編程來說,本質(zhì)上是確定的,對于同樣一段代碼,不管是誰寫的,不管什么時候執(zhí)行,執(zhí)行的結(jié)果應該都是確定的;而對于架構(gòu)設計來說,本質(zhì)上是不確定,并沒有像編程語言那樣的語法來進行約束,更多的時候是面對多種可能性時進行選擇。
?示例:
是要選擇業(yè)界最先進的技術,還是選擇團隊目前最熟悉的技術?
是要選 MySQL 還是 MongoDB?團隊對 MySQL 很熟悉,但是 MongoDB 更加適合業(yè)務場景?
淘寶的電商網(wǎng)站架構(gòu)很完善,我們新做一個電商網(wǎng)站,是否簡單地照搬淘寶就可以了?
1.合適原則
合適優(yōu)于業(yè)界領先。
?在進行架構(gòu)設計的同時,需要考慮自身業(yè)務,而不是一味的去參照業(yè)界頂尖的規(guī)模,如:QQ、微信、淘寶架構(gòu)。真正優(yōu)秀的架構(gòu)都是在企業(yè)當前人力、條件、業(yè)務等各種約束下設計出來的,能夠合理地將資源整合在一起并發(fā)揮出最大功效,并且能夠快速落地。
2.簡單原則
簡單優(yōu)于復雜。
?軟件架構(gòu)設計是一門技術活,當我們進行架構(gòu)設計時,會自然而然地想把架構(gòu)做精美、做復雜,這樣才能體現(xiàn)我們的技術實力,也才能夠?qū)⒓軜?gòu)做成一件藝術品。然而,“復雜”在制造領域代表先進,在建筑領域代表領先,但在軟件領域,卻恰恰相反,代表的是“問題”。
?軟件復雜度的體現(xiàn),主要有以下兩個方面:
結(jié)構(gòu)的復雜性
– 組成復雜系統(tǒng)的組件數(shù)量更多;
– 組件之間的關系也更加復雜。
其問題主要有:
(1)組件越多,就越有可能其中某個組件出現(xiàn)故障,從而導致系統(tǒng)故障。
(2)某個組件改動,會影響關聯(lián)的所有組件。
(3)定位一個復雜系統(tǒng)中的問題總是比簡單系統(tǒng)更加困難。
邏輯的復雜性
邏輯的復雜性來源于一個組件集中了太多的功能,修改協(xié)作困難;并且,其中某些業(yè)務還可能使用了一些復雜的算法,導致難以理解、修改困難。
?一個組件集中了太多功能,就會表現(xiàn)出一些邏輯復雜性的特征,為了解決這個問題,一般的手段是進行組件的拆分,但隨著組件的細化,又會引入結(jié)構(gòu)復雜性的一些特征,所以,在做結(jié)構(gòu)設計的時候,需要權(quán)衡這兩者。
3.演化原則
演化優(yōu)于一步到位。
?維基百科對“軟件架構(gòu)”的定義如下:
從和目的、主題、材料和結(jié)構(gòu)的聯(lián)系上來說,軟件架構(gòu)可以和建筑物的架構(gòu)相比擬。
?這個定義中,將建筑和軟件架構(gòu)做了一個比較,但是,兩者之間是有一個本質(zhì)區(qū)別的:對于建筑來說,永恒是主題;而對于軟件來說,變化才是主題。
?也就是說,軟件架構(gòu)的本質(zhì)是:軟件架構(gòu)需要根據(jù)業(yè)務發(fā)展不斷變化,所以,我們在做軟件架構(gòu)設計的時候,不要試圖一步到位設計一個軟件架構(gòu),期望不管業(yè)務如何變化,架構(gòu)都穩(wěn)如磐石。
?架構(gòu)設計的過程基本上可以總結(jié)為下面三個歷程:
首先,設計出來的架構(gòu)要滿足當時的業(yè)務需要。
其次,架構(gòu)要不斷地在實際應用過程中迭代,保留優(yōu)秀的設計,修復有缺陷的設計,改正錯誤的設計,去掉無用的設計,使得架構(gòu)逐漸完善。-- 小重構(gòu)
最后,當業(yè)務發(fā)生變化時,架構(gòu)要擴展、重構(gòu),甚至重寫;代碼也許會重寫,但有價值的經(jīng)驗、教訓、邏輯、設計等(類似生物體內(nèi)的基因)卻可以在新架構(gòu)中延續(xù)。-- 大重構(gòu)
?我們在做架構(gòu)設計的時候,切勿貪大求全,或者盲目的照搬大公司的做法,而是要牢記軟件架構(gòu)的本質(zhì)(軟件架構(gòu)需要根據(jù)業(yè)務發(fā)展不斷變化)。認真分析當前業(yè)務的特點,明確業(yè)務面臨的主要問題,設計合理的架構(gòu),快速落地以滿足業(yè)務需要,然后在運行過程中不斷完善架構(gòu),不斷隨著業(yè)務演化架構(gòu)。
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/qq_37958845/article/details/108406675


