點(diǎn)擊上方“CSDN”,選擇“置頂公眾號”
關(guān)鍵時刻,第一時間送達(dá)!
作者簡介:,關(guān)注于互聯(lián)網(wǎng)電商,金融,支付等系統(tǒng)領(lǐng)域,10多年研發(fā)管理和架構(gòu)經(jīng)驗(yàn),前阿里架構(gòu)師、某商業(yè)銀行北京研發(fā)中心負(fù)責(zé)人,某電商公司高級技術(shù)總監(jiān)。本文來自作者在上分享 「軟件架構(gòu)發(fā)展歷程分享」。
什么是架構(gòu)
計(jì)算機(jī)科學(xué)和程序設(shè)計(jì)的飛速發(fā)展,使得軟件設(shè)計(jì)應(yīng)用到從航空航天到日常生活的方方面面。單個人開發(fā)一段小程序的做法早就過時,大范圍協(xié)作的工程化時代隨即到來。
隨著大范圍協(xié)作的效率問題和軟件復(fù)雜度的爆炸式增長,管理和技術(shù)方面的各種不確定性也爆發(fā)性增加,導(dǎo)致軟件開發(fā)的質(zhì)量無法得到有效保證,周期和成本無法得到有效控制。
人們一直在尋求找到這些問題的解決辦法。然而 Fred 在 1975 年出版的軟件工程圣經(jīng)《人月神話》中說,沒有(能解決所有問題的)銀彈(There is no )。
自此,人們發(fā)展了項(xiàng)目研發(fā)過程管理來控制管理活動的不確定性,同時也發(fā)展了軟件架構(gòu)設(shè)計(jì)方法來控制技術(shù)方面的不確定性。
進(jìn)而在實(shí)踐中不斷的總結(jié)和改進(jìn),用于有效指導(dǎo)和最大程度的保障軟件開發(fā)的質(zhì)量、周期和成本。
架構(gòu)的定義
架構(gòu)()一詞源于建筑領(lǐng)域,其本身就是建筑的意思,也是體系結(jié)構(gòu)的意思。維基百科英文版里對 的解釋是:規(guī)劃、設(shè)計(jì)和建造建筑物的過程及產(chǎn)物。
鑒于軟件工程與建筑工程一樣是一項(xiàng)系統(tǒng)的工程性工作,引入到計(jì)算機(jī)領(lǐng)域后,軟件架構(gòu)就成為了描述軟件規(guī)劃設(shè)計(jì)技術(shù)的專有名詞。
特別地,軟件架構(gòu)師一詞在英文里,和建筑師也是同一個詞()。
維基百科里對軟件架構(gòu)的定義:
軟件架構(gòu)是有關(guān)軟件整體結(jié)構(gòu)與組件的抽象描述,用于指導(dǎo)大型軟件系統(tǒng)各個方面的設(shè)計(jì)。
軟件架構(gòu)師定義和設(shè)計(jì)軟件的模塊化,模塊之間的交互,用戶界面風(fēng)格,對外接口方法,創(chuàng)新的設(shè)計(jì)特性,以及高層事物的對象操作、邏輯和流程。軟件架構(gòu)是一個系統(tǒng)的草圖。
軟件架構(gòu)描述的對象是直接構(gòu)成系統(tǒng)的抽象組件。各個組件之間的連接則明確和相對細(xì)致地描述組件之間的通訊。
在實(shí)現(xiàn)階段,這些抽象組件被細(xì)化為實(shí)際的組件,比如具體某個類或者對象。在面向?qū)ο箢I(lǐng)域中,組件之間的連接通常用接口來實(shí)現(xiàn)。
比較公認(rèn)的軟件架構(gòu)定義是在 2000 年的 ANSI/IEEE 1471 標(biāo)準(zhǔn)中定義的:
架構(gòu)過程:在系統(tǒng)整個生命周期中構(gòu)思、定義、表達(dá)、記錄、交流,驗(yàn)證合適實(shí)現(xiàn),維護(hù)和改進(jìn)架構(gòu)的過程,也就是設(shè)計(jì)過程。
架構(gòu):一個系統(tǒng)體現(xiàn)在其環(huán)境中的元素、關(guān)系的基本概念或?qū)傩裕约捌湓O(shè)計(jì)和進(jìn)化原則。
架構(gòu)描述:表達(dá)一個架構(gòu)的工作產(chǎn)出物(通常指的是各種架構(gòu)圖和設(shè)計(jì)文檔)。
架構(gòu)視圖:通過系統(tǒng)的某些關(guān)注點(diǎn)的視角,表達(dá)一個系統(tǒng)的工作產(chǎn)出物(例如部署視圖、開發(fā)視圖等)。
系統(tǒng):包含了一個或多個進(jìn)程、硬件、軟件、工具與可以滿足需求的人的集合。
環(huán)境:決定了開發(fā)、操作、策略和其他影響系統(tǒng)的設(shè)置和條件。
在 UML 中,架構(gòu)則被認(rèn)為是系統(tǒng)的組織結(jié)構(gòu)和相關(guān)行為。架構(gòu)可被分解為通過接口互聯(lián)部分的關(guān)系,以及相互作用。
通過接口相互作用的部分包括類、組件和子系統(tǒng)。這樣就可以通過 UML 的各種架構(gòu)圖來描述這些對象和關(guān)系,從而表達(dá)清楚一個系統(tǒng)的架構(gòu)。
總結(jié)
軟件架構(gòu)是一個用于指導(dǎo)系統(tǒng)實(shí)現(xiàn)的草圖,這個草圖越詳細(xì)對于系統(tǒng)實(shí)現(xiàn)的指導(dǎo)意義越重大,貫穿于軟件的整個生命周期。
在建筑領(lǐng)域,大樓尚未建造前,就已經(jīng)存在于建筑師的腦海里;同樣地,系統(tǒng)開始編寫第一行代碼之前,就已經(jīng)存在于軟件架構(gòu)師的心里。
幾個相關(guān)概念
模式()
UML 中給出的解釋更通俗易懂:模式是對于普遍問題的普遍解決方案。
我們可以把一類問題的共性抽象出來,這樣就可以用同樣的處理辦法去解決這些問題,從而形成模式,所以模式是一些經(jīng)驗(yàn)的總結(jié)。
類庫()
類庫是一組可復(fù)用的功能或工具的集合,應(yīng)用系統(tǒng)通過調(diào)用它們從而達(dá)到復(fù)用功能的目的。
例如, 應(yīng)用開發(fā)里的各種靜態(tài)或動態(tài)鏈接庫 DLL 文件,Java 開發(fā)中項(xiàng)目里依賴的或者 Maven 中央庫里的各種 jar 包,都是 ,比如 IO、,Log4j 等。
框架()
框架是基于一組類庫或工具,在特定領(lǐng)域里根據(jù)一定的規(guī)則組合成的、開放性的應(yīng)用骨架。
比如 SSM/SSH 框架軟件易用性需求,更大范圍來說 、JDK 都算是一種框架。
關(guān)于框架與架構(gòu)的關(guān)系,Vasyl 曾在 Stack 網(wǎng)站上通過兩張圖做了形象的對比,如下所示。
模塊()
模塊是業(yè)務(wù)或系統(tǒng)的安裝特定維度的一種切分,同時也可以看做是各種功能按照某種分類聚合的一種形式。
例如我們的一個電商系統(tǒng),可以從業(yè)務(wù)上劃分為用戶模塊、商品模塊、訂單模塊、支付模塊、物流模塊、售后模塊等。
另一方面,我們也可以說用戶模塊聚合了用戶注冊、用戶驗(yàn)證等業(yè)務(wù)功能。
組件()
組件是一組可以復(fù)用的業(yè)務(wù)功能的集合,包含一些對象及其行為。
組件可以直接被用做業(yè)務(wù)系統(tǒng)的組成部分,粒度一般小于模塊,也是一種功能的聚合形式。比如日志組件、權(quán)限組件等。
服務(wù)()
服務(wù)是一組對外提供業(yè)務(wù)處理能力的功能,服務(wù)需要使用明確的接口方式(比如 或 Rest 等)。
服務(wù)描述里應(yīng)該包括約束和策略(比如參數(shù)、返回值,使用什么通訊協(xié)議和數(shù)據(jù)格式等)。
平臺()
平臺一般來說,是一個領(lǐng)域或方向上的生態(tài)系統(tǒng),是很多解決方案的集大成者,提供了很多的服務(wù)、接口、規(guī)范、標(biāo)準(zhǔn)、功能、工具等。
例如 J2EE 平臺,包含了企業(yè)級應(yīng)用開發(fā)里的各種基于 Java 語言和 JVM 虛擬機(jī)運(yùn)行時的技術(shù)能力。
知乎社區(qū)編程領(lǐng)域優(yōu)秀問題回答者 ze ran 說:
庫是工具箱。
框架是一套通用的解決方案。
架構(gòu)是高度抽象的需求,是系統(tǒng)中的不變量。
平臺是所有可能做的事的集合。
從軟件的生命周期看架構(gòu)設(shè)計(jì)
設(shè)計(jì)期
在設(shè)計(jì)期,軟件作為一個成品還不存在,所以我們可以稱之為概念形態(tài)。
此時架構(gòu)師、產(chǎn)品經(jīng)理或需求分析師等人員利用自己的經(jīng)驗(yàn)?zāi)芰Γ瑢ο到y(tǒng)的業(yè)務(wù)需求進(jìn)行分析、拆解、抽象,形成業(yè)務(wù)文檔和技術(shù)文檔,以及技術(shù)驗(yàn)證代碼等。
這個階段,架構(gòu)設(shè)計(jì)工作是重中之重,其中包括:
這個階段總結(jié)一下就是:業(yè)務(wù)為要,架構(gòu)先行(包括業(yè)務(wù)架構(gòu)和技術(shù)架構(gòu))。
實(shí)現(xiàn)期
這個階段主要是編碼與測試,準(zhǔn)備部署上線,是軟件從代碼到最終的生產(chǎn)系統(tǒng)的過程,我們可以稱之為代碼形態(tài)。此階段需要考慮的技術(shù)類工作包括:
運(yùn)行期
這個階段系統(tǒng)上線、驗(yàn)收通過,已經(jīng)初步穩(wěn)定,然后進(jìn)入維護(hù)階段,成為了設(shè)計(jì)期架構(gòu)設(shè)計(jì)草圖的一個可用實(shí)例,我們可以稱之為實(shí)例形態(tài)。此時需要考慮:
架構(gòu)的形式與特點(diǎn)
設(shè)計(jì)文檔和代碼
我們一般說的架構(gòu)既包括架構(gòu)的設(shè)計(jì)過程,也包括設(shè)計(jì)的產(chǎn)出物,一般可以包括各類設(shè)計(jì)文檔、設(shè)計(jì)圖,也可以包括一些技術(shù)驗(yàn)證代碼、Demo 或者其他相關(guān)程序。
文檔的目的在于準(zhǔn)確記錄我們的思維產(chǎn)物,在軟件尚未實(shí)現(xiàn)時,作為指導(dǎo)藍(lán)圖,盡量精確的描述清楚軟件。
在軟件的實(shí)現(xiàn)過程中,可能隨時隨著我們的深入研究,根據(jù)具體情況對文檔做出局部的一些調(diào)整和修改。
文檔作為結(jié)項(xiàng)或交接的一部分,也是整個軟件項(xiàng)目的產(chǎn)出物的一部分,成為公司 IT 資產(chǎn)的有機(jī)組成部分。
架構(gòu)服務(wù)于業(yè)務(wù)
正如 19 世紀(jì)的偉大建筑師路易斯?沙利文(Louis )倡導(dǎo)的建筑設(shè)計(jì)著名格言:“功能決定形式(Form )”。
軟件架構(gòu)首先是要服務(wù)于業(yè)務(wù)功能的。
架構(gòu)影響研發(fā)團(tuán)隊(duì)的組織形式
業(yè)務(wù)拆分的方法和技術(shù)框架的選擇必然會影響到研發(fā)團(tuán)隊(duì)的組織形式。
業(yè)務(wù)拆分的越細(xì)致,越有利于我們更好的對項(xiàng)目的各項(xiàng)指標(biāo)量化計(jì)算,更精確的估計(jì)工時和成本,從而指導(dǎo)我們每個小組應(yīng)該分配多少資源,使用什么樣的協(xié)同和任務(wù)確認(rèn)形式。
并且隨著項(xiàng)目的推進(jìn),計(jì)劃與實(shí)際情況之間的匹配程度也隨時可以進(jìn)一步精確調(diào)整,進(jìn)而影響到我們應(yīng)該對每一塊任務(wù)的投入資源進(jìn)行動態(tài)調(diào)整。
架構(gòu)存在于每一個系統(tǒng)
每一個已經(jīng)實(shí)現(xiàn)并運(yùn)行的系統(tǒng),都是特定架構(gòu)設(shè)計(jì)的載體。
有些系統(tǒng)對應(yīng)的架構(gòu),有詳細(xì)的設(shè)計(jì)文檔來描述;有些系統(tǒng)的設(shè)計(jì)文檔,殘缺不全,甚至還因?yàn)樵谙到y(tǒng)的發(fā)展變化的同時,文檔沒有更新,導(dǎo)致設(shè)計(jì)文檔與實(shí)際系統(tǒng)不符。
有些系統(tǒng)干脆就沒有設(shè)計(jì)文檔。
但是這些系統(tǒng),都是基于一定的架構(gòu)來創(chuàng)建的。
每種架構(gòu)都有特定的架構(gòu)風(fēng)格
每種架構(gòu)方式,每個具體系統(tǒng)內(nèi)所體現(xiàn)的架構(gòu)設(shè)計(jì),都是可以被工程師們理解,進(jìn)而提煉出來一些架構(gòu)思想和設(shè)計(jì)原則,這些思想和原則就是這種架構(gòu)方式的風(fēng)格。依據(jù)這些風(fēng)格,我們可以將各種架構(gòu)方式,進(jìn)行分門別類軟件易用性需求,從而進(jìn)一步討論每種架構(gòu)風(fēng)格的特點(diǎn)。
架構(gòu)需要不斷的發(fā)展演進(jìn)
隨著計(jì)算機(jī)軟硬件的不斷發(fā)展,軟件架構(gòu)思想也在不斷的發(fā)展變化。
另一方面,軟件為其提供業(yè)務(wù)處理和服務(wù)能力的每個具體行業(yè)領(lǐng)域也在不斷發(fā)展變化,業(yè)務(wù)處理流程、參與角色、業(yè)務(wù)形式不斷的推陳出新。
這就要求我們在系統(tǒng)架構(gòu)設(shè)計(jì)時,保持終身學(xué)習(xí)的精神,持續(xù)吸收新思想新知識,保持貼近一線業(yè)務(wù)群體,隨時因地制宜,調(diào)整架構(gòu)設(shè)計(jì),采取最適合當(dāng)下場景的解決方案。
架構(gòu)的目標(biāo)與方法
明確軟件系統(tǒng)架構(gòu)的一些通用目標(biāo),可以使我們更明確如何考慮架構(gòu)的方向;而了解架構(gòu)的方法和方法論,則讓我們可以知道從哪些角度可以比較全面的描述清楚一個系統(tǒng)的架構(gòu)設(shè)計(jì)。
可控性與拆分
對于復(fù)雜問題的簡化處理,一個簡單辦法就是分而治之。
按一定的粒度把目標(biāo)問題進(jìn)行分解,可以非常有效的提升目標(biāo)的可控性,使得目標(biāo)變得更加可以量化、進(jìn)而優(yōu)化。
系統(tǒng)按照合適的粒度拆分成不同模塊的過程,我們一般稱為模塊化。模塊化也是軟件工程化的基礎(chǔ)。
在這個基礎(chǔ)上才能夠?qū)崿F(xiàn)分工合作。
復(fù)用性與抽象
復(fù)用性一直是軟件設(shè)計(jì)領(lǐng)域的一個很重要的指標(biāo)。
復(fù)用的一個關(guān)鍵是我們對于現(xiàn)有具體問題的抽象,找到各種不同問題中存在的不變性,進(jìn)而作為一種通用結(jié)構(gòu)來統(tǒng)一處理。
拆成是把整體變成很多局部,再對局部分開對待和研究其性質(zhì)。
反過來,我們按照高內(nèi)聚的指導(dǎo)思想把一些緊密聯(lián)系的功能聚合后,打包成一個可以整體復(fù)用的部分,這就是組件,這個過程就是組件化。
通過組件化,我們可以得到抽象再組合出來很多業(yè)務(wù)組件。這樣,在更大粒度上實(shí)現(xiàn)了功能的復(fù)用。
非功能性需求九維目標(biāo)
(1)高性能
系統(tǒng)必須滿足預(yù)期的性能目標(biāo),在并發(fā)用戶數(shù)( Users)、并發(fā)事務(wù)數(shù)( per ,TPS)、吞吐量()等指標(biāo)方面達(dá)到預(yù)估值,支撐使用人群的正常使用操作。
(2)可靠性
業(yè)務(wù)系統(tǒng)直接影響到用戶的經(jīng)營和管理,因此必須是可靠的。
(3) 穩(wěn)定性
軟件系統(tǒng)必須是能夠在用戶的使用周期內(nèi)長期穩(wěn)定運(yùn)行的。這要求系統(tǒng)具有一定的容錯能力。
(4)可用性
可用性是指系統(tǒng)在指定時間內(nèi)的提供服務(wù)能力的概率值。我們一般采取集群、分布式等手段提升系統(tǒng)的可用性。
高可用性是目前系統(tǒng)架構(gòu)設(shè)計(jì)方面的一個熱點(diǎn)。
(5)安全性
用戶的業(yè)務(wù)數(shù)據(jù)是具有非常高的商業(yè)價(jià)值,如果被泄露或篡改將會帶來重大損失。
安全性是軟件系統(tǒng)的一個重要的指標(biāo),也是架構(gòu)設(shè)計(jì)的一個重要目標(biāo)。
(6)靈活性
軟件系統(tǒng)應(yīng)該具備滿足不同特點(diǎn)的用戶群和目標(biāo)市場的能力,更靈活。
(7)易用性
軟件系統(tǒng)必須擁有較好的用戶體驗(yàn),便于用戶使用。
(8)可擴(kuò)展性
業(yè)務(wù)和技術(shù)都在不斷的發(fā)展變化,軟件系統(tǒng)需要隨時根據(jù)變化擴(kuò)展改造的能力。
(9)可維護(hù)性
軟件系統(tǒng)的維護(hù)包括修復(fù)現(xiàn)有的錯誤,以及將新的需求和改進(jìn)添加到已有系統(tǒng)。
因此一個易于維護(hù)的系統(tǒng)對于用戶提出的問題或改進(jìn),可以及時的實(shí)現(xiàn)高效的反饋和響應(yīng)支持,同時有效降低維護(hù)成本。
基于這些目標(biāo),經(jīng)常有人說:“架構(gòu)是系統(tǒng)非功能性需求的解決辦法的集合”。
架構(gòu)的不同風(fēng)格
典型的企業(yè)級應(yīng)用系統(tǒng)或者互聯(lián)網(wǎng)應(yīng)用系統(tǒng)一般都是通過 Web 提供一組業(yè)務(wù)服務(wù)能力。
這類系統(tǒng)包括提供給用戶操作的、運(yùn)行于瀏覽器中、具有 UI 的業(yè)務(wù)邏輯展示和輸入部分,運(yùn)行于服務(wù)器端、用后端編程語言構(gòu)建的業(yè)務(wù)邏輯處理部分,以及用于存儲業(yè)務(wù)數(shù)據(jù)的關(guān)系數(shù)據(jù)庫或其他類型的存儲軟件。
根據(jù)軟件系統(tǒng)在運(yùn)行期的表現(xiàn)風(fēng)格和部署結(jié)構(gòu),我們可以粗略地將其劃分為兩大類。
(1)整個系統(tǒng)的所有功能單元,整體部署到同一個進(jìn)程(所有代碼可以打包成 1 個或多個文件),我們可以稱之為 “單體架構(gòu)”( );
(2)整個系統(tǒng)的功能單元分散到不同的進(jìn)程,然后由多個進(jìn)程共同提供不同的業(yè)務(wù)能力,我們稱之為 “分布式架構(gòu)”( )。
再結(jié)合軟件系統(tǒng)在整個生命周期的特點(diǎn),我們可以進(jìn)一步區(qū)分不同的架構(gòu)風(fēng)格。
對于單體架構(gòu),我們根據(jù)設(shè)計(jì)期和開發(fā)實(shí)現(xiàn)期的不同模式和劃分結(jié)構(gòu),可以分為:
對于分布式架構(gòu),我們根據(jù)設(shè)計(jì)期的架構(gòu)思想和運(yùn)行期的不同結(jié)構(gòu),可以分為:
也有人把如上的各個架構(gòu)風(fēng)格總結(jié)為四個大的架構(gòu)發(fā)展階段:
這種分類跟前述的方式并沒有多大區(qū)別。我們接下來詳細(xì)介紹其中的一些重要架構(gòu)風(fēng)格。
單體架構(gòu):簡單單體模式
簡單單體模式是最簡單的架構(gòu)風(fēng)格,所有的代碼全都在一個項(xiàng)目中。這樣研發(fā)團(tuán)隊(duì)的任何一個人都可以隨時修改任意的一段代碼,或者增加一些新的代碼。
開發(fā)人員也可以只在自己的電腦上就可以隨時開發(fā)、調(diào)試、測試整個系統(tǒng)的功能。
也不需要額外的一些依賴條件和準(zhǔn)備步驟,我們就可以直接編譯打包整個系統(tǒng)代碼,創(chuàng)建一個可以發(fā)布的二進(jìn)制版本。
這種方式對于一個新團(tuán)隊(duì)的創(chuàng)立初期,需要迅速開始從 0 到 1,抓住時機(jī)實(shí)現(xiàn)產(chǎn)品最短時間推向市場,可以省去各種額外的設(shè)計(jì),直接上手干活,爭取了時間,因而是非常有意義的。
但是這種方式對于一個系統(tǒng)的長期穩(wěn)定發(fā)展確實(shí)有很多壞處的。
首先,簡單單體模式的系統(tǒng)存在代碼嚴(yán)重耦合的問題。所有的代碼都在一起,就算是按照 來切分了不同的模塊,各不同模塊的代碼還是可以直接相互引用。
這就導(dǎo)致了系統(tǒng)內(nèi)的對象間依賴關(guān)系混亂,修改一處代碼,可能會影響一大片的功能無法正常使用。
第二,簡單單體模式的系統(tǒng)變更對部署影響大,并且這個問題是所有的單體架構(gòu)系統(tǒng)都存在的問題。
系統(tǒng)作為一個單體部署,每次發(fā)布的部署單元就是一個新版本的整個系統(tǒng),系統(tǒng)內(nèi)的任何業(yè)務(wù)邏輯調(diào)整都會導(dǎo)致整個系統(tǒng)的重新打包,部署、停機(jī)、再重啟,進(jìn)而導(dǎo)致了系統(tǒng)的停機(jī)發(fā)布時間較長。
每次發(fā)布上線都是生產(chǎn)系統(tǒng)的重大變更,這種部署模式大大提升了系統(tǒng)風(fēng)險(xiǎn),降低了系統(tǒng)的可用性。
第三,簡單單體模式的系統(tǒng)影響開發(fā)效率。
如果一個使用 Java 的簡單單體項(xiàng)目代碼超過 100 萬行,那么在一臺筆記本電腦上修改了代碼后執(zhí)行自動編譯,可能需要等待十分鐘以上,并且內(nèi)存可能不夠編譯過程使用,這是非常難以忍受的。
第四,簡單單體模式打包后的部署結(jié)構(gòu)可能過于龐大,導(dǎo)致業(yè)務(wù)系統(tǒng)啟動很慢,進(jìn)而也會影響系統(tǒng)的可用性。
這一條也是所有單體架構(gòu)的系統(tǒng)都有的問題。
第五,擴(kuò)展性受限,也是所有單體架構(gòu)的一個問題。
如果任何一個業(yè)務(wù)存在性能問題,那么都需要考慮多部署幾個完整的實(shí)例的集群,或者再加上負(fù)載均衡設(shè)備,才能保證整個系統(tǒng)的性能可以支撐用戶的使用。
所以,簡單單體模式比較適用于規(guī)模較小的系統(tǒng),特別是需要快速推出原型實(shí)現(xiàn),以質(zhì)量換速度的場景。
單體架構(gòu):MVC 模式
MVC 也是一個非常常見的 3 層(3-Tier)結(jié)構(gòu)架構(gòu)模式,它把每個模塊劃分為模型層(Model Layer)、視圖層(View Layer)、控制器層( Layer)等部分。
更一般地,我們可以添加數(shù)據(jù)操作層(Data Layer)等,形成一個 N 層(N-Tier)結(jié)構(gòu)模型。
整個系統(tǒng)由多個模塊組成,每個模塊又由這種不同的部分組成。這樣一來,我們就把整個系統(tǒng)拆解成了很多粒度較小的零件。這種方式之所以流行開來,主要是因?yàn)椋?/p>
當(dāng)然,MVC 模式也存在定義不夠明確,對于簡單的業(yè)務(wù)場景拆解過細(xì)導(dǎo)致復(fù)雜度增加等問題,需要在實(shí)踐中不斷摸索和總結(jié)應(yīng)用經(jīng)驗(yàn)。
基于單體架構(gòu)下的 MVC 模式依然解決不了單體架構(gòu)本身存在的問題,特別是對于可用性和擴(kuò)展性的影響。
單體架構(gòu):前后端分離模式
傳統(tǒng)的 Web 系統(tǒng)都是 BS 結(jié)構(gòu)的。
一般的 JSP 或頁面標(biāo)簽 Tag 技術(shù)、后端 或 等模板技術(shù)導(dǎo)致 HTML/CSS/ 等前端技術(shù)與后端的處理邏輯和數(shù)據(jù)耦合到一起,這種方式明顯不符合現(xiàn)代工程化的專業(yè)領(lǐng)域細(xì)分原則。
特別是隨著富網(wǎng)絡(luò)應(yīng)用程序(Rich ,RIA)概念的興起,Ajax 和 框架,前端 UI 組件技術(shù)的大行其道,程序員們在瀏覽器端寫了很多邏輯處理和界面處理的 代碼。
后來越來越多的業(yè)務(wù)邏輯需要在瀏覽器端實(shí)現(xiàn),前端技術(shù)逐漸發(fā)展到了一個百花齊放的階段,特別是近年來基于 前端技術(shù)棧的成功應(yīng)用,最終使前端技術(shù)成為了一個與后端技術(shù)領(lǐng)域并駕齊驅(qū)的領(lǐng)域。
其實(shí)早在 2006 年,ExtJS 作為當(dāng)時的前端解決方案集大成者,已經(jīng)實(shí)現(xiàn)了前端代碼邏輯和界面全部都由 完成,后端只提供基于 URL 的 JSON 數(shù)據(jù)接口。
這樣 Web 系統(tǒng)就由原來的 BS 系統(tǒng),變成了提供 UI 和交互的前端 B 系統(tǒng),提供數(shù)據(jù)接口的后端 S 系統(tǒng),從而達(dá)到了前后端分離的目標(biāo)。
自從,越來越多的系統(tǒng)采用前后端分離的模式,并且進(jìn)一步影響了研發(fā)團(tuán)隊(duì)的組成:前端團(tuán)隊(duì)負(fù)責(zé)前端系統(tǒng)開發(fā),后端團(tuán)隊(duì)負(fù)責(zé)后端系統(tǒng)開發(fā),兩個團(tuán)隊(duì)一起制定前后端系統(tǒng)的數(shù)據(jù)接口。
只要數(shù)據(jù)接口保持穩(wěn)定不變,那么前后端系統(tǒng)可以各自獨(dú)立發(fā)展和維護(hù)。這一條準(zhǔn)則不僅僅是單體架構(gòu)獨(dú)有的,所有的 Web 系統(tǒng)都可以按照這種方式進(jìn)行設(shè)計(jì)。
前后端分離模式一直影響到現(xiàn)在的系統(tǒng)架構(gòu)方法,成為了當(dāng)下的一種最佳實(shí)踐。目前最主流的三種前端開發(fā)框架(React、、Vue),都遵循著這種設(shè)計(jì)理念。
分布式架構(gòu):面向服務(wù)架構(gòu)(SOA)
面向服務(wù)架構(gòu)(SOA)是一種建設(shè)企業(yè) IT 生態(tài)系統(tǒng)的架構(gòu)指導(dǎo)思想。SOA 的關(guān)注點(diǎn)是服務(wù)。服務(wù)最基本的業(yè)務(wù)功能單元,由平臺中立性的接口契約來定義。
通過將業(yè)務(wù)系統(tǒng)服務(wù)化,可以將不同模塊解耦,各種異構(gòu)系統(tǒng)間可以輕松實(shí)現(xiàn)服務(wù)調(diào)用、消息交換和資源共享。
(1)從宏觀的視角來看,不同于以往的孤立業(yè)務(wù)系統(tǒng),SOA 強(qiáng)調(diào)整個企業(yè) IT 生態(tài)環(huán)境是一個大的整體。整個 IT 生態(tài)中的所有業(yè)務(wù)服務(wù)構(gòu)成了企業(yè)的核心 IT 資源。
各系統(tǒng)的業(yè)務(wù)拆解為不同粒度和層次的模塊和服務(wù),服務(wù)可以組裝到更大的粒度,不同來源的服務(wù)可以編排到同一個處理流程,實(shí)現(xiàn)非常復(fù)雜的集成場景和更加豐富的業(yè)務(wù)功能。
(2)從研發(fā)的視角來看,系統(tǒng)的復(fù)用可以從以前代碼級的粒度,擴(kuò)展到業(yè)務(wù)服務(wù)的粒度;能夠快速應(yīng)對業(yè)務(wù)需求和集成需求的變更。
(3)從管理的角度來看,SOA 從更高的層次對整個企業(yè) IT 生態(tài)進(jìn)行統(tǒng)一的設(shè)計(jì)與管理,對消息處理與服務(wù)調(diào)用進(jìn)行監(jiān)控,優(yōu)化資源配置,降低系統(tǒng)復(fù)雜度和綜合成本,為業(yè)務(wù)流程梳理和優(yōu)化提供技術(shù)支撐。
SOA 的落地方式與水平,跟企業(yè) IT 特點(diǎn)、服務(wù)能力和發(fā)展階段直接相關(guān)。目前常見的落地方式主要有分布式服務(wù)化和集中式管理兩種。
(1)分布式服務(wù)化
互聯(lián)網(wǎng)類型的企業(yè),業(yè)務(wù)與技術(shù)發(fā)展快,數(shù)據(jù)基數(shù)與增量都大,并發(fā)訪問量高,系統(tǒng)間依賴關(guān)系復(fù)雜、調(diào)用頻繁,分布式服務(wù)化與服務(wù)治理迫在眉睫。
通過統(tǒng)一的服務(wù)化技術(shù)手段,進(jìn)一步實(shí)現(xiàn)服務(wù)的注冊與尋址、服務(wù)調(diào)用關(guān)系查找、服務(wù)調(diào)用與消息處理監(jiān)控、服務(wù)質(zhì)量與服務(wù)降級等等。
現(xiàn)有的一些分布式服務(wù)化技術(shù)有 Dubbo(基于 Java)、(基于 Scala)和 ICE(跨平臺)等。
(2)集中式管理
傳統(tǒng)企業(yè)的 IT 內(nèi)部遺留系統(tǒng)包袱較重,資源整合很大一部分是需要打通新舊技術(shù)體系的任督二脈,所以更偏重于以 ESB 作為基礎(chǔ)支撐技術(shù)。
以整合集成為核心,將各個新舊系統(tǒng)的業(yè)務(wù)能力逐漸的在 ESB 容器上聚合和集成起來。
比較流行的商業(yè) ESB 有 IBM 的 WMB 和 的 OSB,開源 ESB 有 Mule、/WSO2 ESB、JBoss ESB 和 。
一方面,集中式管理的 SOA,其優(yōu)勢在于管理和集成企業(yè)內(nèi)部各處散落的業(yè)務(wù)服務(wù)能力,同時一個明顯的不足在于其中心化的架構(gòu)方法,并不能解決各個系統(tǒng)自己內(nèi)部的問題。
另一方面,隨著自動化測試技術(shù)、輕量級容器技術(shù)等相關(guān)技術(shù)的發(fā)展,分布式服務(wù)技術(shù)越來越像微服務(wù)架構(gòu)方向發(fā)展。
分布式架構(gòu):微服務(wù)架構(gòu)(MSA)
James Lewis 和 給微服務(wù)架構(gòu)的定義如下:
微服務(wù)架構(gòu)風(fēng)格,以實(shí)現(xiàn)一組微服務(wù)的方式來開發(fā)一個獨(dú)立的應(yīng)用系統(tǒng)的方法。其中每個小微服務(wù)都運(yùn)行在自己的進(jìn)程中,一般采用 HTTP 資源 API 這樣輕量的機(jī)制相互通信。
這些微服務(wù)圍繞業(yè)務(wù)功能進(jìn)行構(gòu)建,通過全自動化的部署方式來進(jìn)行獨(dú)立部署。這些微服務(wù)可以使用不同的語言來編寫,也可以使用不同的數(shù)據(jù)存儲技術(shù),并且基于最低限度的集中管理。
同時 總結(jié)有如下 9 個特性:
微服務(wù)架構(gòu)可以看作是一種 SOA 的發(fā)展實(shí)現(xiàn),其將 SOA 中原本可能聚合在同一個系統(tǒng)內(nèi)的多個服務(wù)組件拆分到各自獨(dú)立的系統(tǒng)進(jìn)程。
微服務(wù)架構(gòu)的優(yōu)勢在于:
微服務(wù)架構(gòu)的劣勢也很明顯,拆分的過細(xì)則要求自動化測試能力必須跟得上。一個全流程的測試跨 8~10 個系統(tǒng)是所有測試人員的惡魔。
問題的排查,數(shù)據(jù)的一致性保障,系統(tǒng)的監(jiān)控等等,都會因?yàn)椴鸱值奶?xì),復(fù)雜度大幅度增加。
如果代碼或設(shè)計(jì)上有一個修改涉及到多個不同的微服務(wù),那么在團(tuán)隊(duì)之間協(xié)調(diào)配合成本也會增加。對舊系統(tǒng)的微服務(wù)架構(gòu)和組件化改造也是一個比較大的問題。
在組件化上所做的任何工作的成功度,取決于軟件與組件的匹配程度。
但是合理的組件邊界應(yīng)該如何確定,這是非常困難的,演進(jìn)式的處理方式是我們覺得比較合理和靠譜的。
因此, 也建議,不要一上來就以微服務(wù)架構(gòu)作為系統(tǒng)設(shè)計(jì)的起點(diǎn)。相反地,要用一個單塊系統(tǒng)作為起點(diǎn),并保持其模塊化。
當(dāng)這個單塊系統(tǒng)出現(xiàn)了問題后,再將其分解為微服務(wù)。