一、目錄
架構的常識
1. 什么是架構?
2. 為什么需要架構?
3. 架構師的職責軟件架構
軟件架構分類
典型應用架構
1. 分層架構
2. CQRS
3. 六邊形架構
4. 洋蔥圈架構COLA 應用架構
1. 分層設計
2. 擴展設計
3. 規范設計
4. COLA 架構總覽應用架構的核心
二、架構的常識
1. 什么是架構?
關于架構這個概念很難給出一個明確的定義,也沒有一個標準的定義。
系統構架是對已確定的需求的技術實現構架、作好規劃,運用成套、完整的工具,在規劃的步驟下去完成任務。抽象來說,它是計算機系統結構,或稱計算機體系結構,是一個系統在其所處環境中最高層次的概念。
架構始于建筑,是因為人類發展(原始人自給自足住在樹上,也就不需要架構),分工協作的需要,將目標系統按某個原則進行切分,切分的原則,是要便于不同的角色進行并行工作。
2. 為什么需要架構?
有系統的地方就需要架構,大到航空飛機,小到一個電商系統里面的一個功能組件都需要設計和架構。
與之相對應的,現在很多敏捷思想提倡 no design,只要 work 就好。期待好的架構可以在迭代中自然涌現。這個想法有點太理想化了,在現實中,只要能 work 的代碼,工程師是很少有動力去重構和優化的。
3. 架構師的職責
作為架構師,我們最重要的價值應該是“化繁為簡”。但凡讓事情變得更復雜,讓系統變得更晦澀難懂的架構都是值得商榷的。
架構師的工作就是要努力訓練自己的思維,用它去理解復雜的系統,通過合理的分解和抽象,使哪些系統不再那么難懂 。我們應該努力構建易懂的架構,使得在系統上工作的其他人員(例如設計者、實現者、操作員等)可以較為容易地理解這個系統。
三、軟件架構
軟件架構是一個系統的草圖。軟件架構描述的對象是直接構成系統的抽象組件。各個組件之間的連接則明確和相對細致地描述組件之間的通信。在實現階段,這些抽象組件被細化為實際的組件,比如具體某個類或者對象。在面向對象領域中,組件之間的連接通常用接口來實現。
軟件架構為軟件系統提供了一個結構、行為和屬性的高級抽象 ,由構件的描述、構件的相互作用、指導構件集成的模式以及這些模式的約束組成。軟件架構不僅顯示了軟件需求和軟件結構之間的對應關系,而且指定了整個軟件系統的組織和拓撲結構,提供了一些設計決策的基本原理。
軟件架構的核心價值應該只圍繞一個核心命題:控制復雜性。他并不意味著某個特定的分層結構,某個特定的方法論(貧血、DDD 等)。
四、 軟件架構分類
在介紹應用架構之前,我們先來看一下軟件架構的分類。
隨著互聯網的發展,現在的系統要支撐數億人同時在線購物、通信、娛樂的需要,相應的軟件體系結構也變得越來越復雜。軟件架構的含義也變得更加寬泛,我們不能簡單地用一個軟件架構來指代所有的軟件架構工作。按照我個人理解,將軟件架構劃分為:
4.1 業務架構
由業務架構師負責,也可以稱為業務領域專家、行業專家。業務架構屬于頂層設計,其對業務的定義和劃分會影響組織結構和技術架構。例如,阿里巴巴在沒有中臺部門之前,每個業務部門的技術架構都是煙囪式的,淘寶、天貓、飛豬、1688 等各有一套體系結構。而后,成立了共享平臺事業部,打通了賬號、商品、訂單等體系,讓商業基礎實施的復用成為可能。
4.2應用架構
由應用架構師負責,他需要根據業務場景的需要,設計應用的層次結構,制定應用規范、定義接口和數據交互協議等。并盡量將應用的復雜度控制在一個可以接受的水平,從而在快速的支撐業務發展的同時,在保證系統的可用性和可維護性的同時,確保應用滿足非功能屬性要求(性能、安全、穩定性等)。
4.3分布式系統架構
分布式系統基本是稍具規模業務的必選項。它需要解決服務器負載,分布式服務的注冊和發現,消息系統,緩存系統,分布式數據庫等問題,同時架構師要在 CAP(Consistency,Availability,Partition tolerance)之間進行權衡。
4.4數據架構
對于規模大一些的公司,數據治理是一個很重要的課題。如何對數據收集、數據處理提供統一的服務和標準,是數據架構需要關注的問題。其目的就是統一數據定義規范,標準化數據表達,形成有效易維護的數據資產,搭建統一的大數據處理平臺,形成數據使用閉環。
4.5物理架構
物理架構關注軟件元件是如何放到硬件上的,包括機房搭建、網絡拓撲結構,網絡分流器、代理服務器、Web 服務器、應用服務器、報表服務器、整合服務器、存儲服務器和主機等。
4.6運維架構
負責運維系統的規劃、選型、部署上線,建立規范化的運維體系。
五、典型應用架構
5.1. 分層架構
分層是一種常見的根據系統中的角色(職責拆分)和組織代碼單元的常規實踐。常見的分層結構如下圖所示:
5.2. CQRS
CQS(Command Query Separation,命令查詢分離),最早來自于 Betrand Meyer(Eiffel 語言之父,OCP 提出者)提出的概念。其基本思想在于,任何一個對象的方法可以分為兩大類:
命令 (Command): 不返回任何結果(void),但會改變對象的狀態。
查詢 (Query): 返回結果,但是不會改變對象的狀態,對系統沒有副作用。
5.3. 六邊形架構
六邊形架構是 Alistair Cockburn 在 2005 年提出,解決了傳統的分層架構所帶來的問題,實際上它也是一種分層架構,只不過不是上下,而是變成了內部和外部(如下圖所示)。
六邊形架構又稱為端口-適配器架構,這個名字更容器理解。六邊形架構將系統分為內部(內部六邊形)和外部,內部代表了應用的業務邏輯,外部代表應用的驅動邏輯、基礎設施或其他應用。
適配器分為兩種類型(如下圖所示),左側代表 UI 的適配器被稱為主動適配器 (Driving Adapters),因為是它們發起了對應用的一些操作。而右側表示和后端工具鏈接的適配器,被稱為被動適配器 (Driven Adapters),因為它們只會對主適配器的操作作出響應。
5.4. 洋蔥圈架構
洋蔥架構與六邊形架構有著相同的思路,它們都通過編寫適配器代碼將應用核心從對基礎設施的關注中解放出來,避免基礎設施代碼滲透到應用核心之中。這樣應用使用的工具和傳達機制都可以輕松地替換,可以一定程度地避免技術、工具或者供應商鎖定。
不同的是洋蔥架構還告訴我們,企業應用中存在著不止兩個層次,它在業務邏輯中加入了一些在領域驅動設計的過程中被識別出來的層次(Application,Domain Service,Domain model,Infrastructure 等)。
另外,它還有著脫離真實基礎設施和傳達機制應用仍然可以運行的便利,這樣可以使用 mock 代替它們方便測試。
在洋蔥架構中,明確規定了依賴的方向:
- 外層依賴內層
- 內層對外層無感知
六、COLA 應用架構
COLA 架構是阿里自主研發的應用架構,目前已經開源。在 COLA 的設計中,充分汲取了經典架構的優秀思想。除此之外,補充了規范設計和擴展設計,并且使用 Archetype 的方式,將架構固化下來,以便可以快速的在開發中使用。
COLA 開源地址:https://github.com/alibaba/COLA
6.1. 分層設計
COLA 的分層是一種改良了的三層架構。主要是將傳統的業務邏輯層拆分成應用層、領域層和基礎實施層。如下圖所示,左邊是傳統的分層架構,右邊是 COLA 的分層架構。
其每一層的作用范圍和含義如下:
1)展現層(Presentation Layer)
負責以 Rest 的格式接受 Web 請求,然后將請求路由給 Application 層執行,并返回視圖模型(View Model),其載體通常是 DTO(Data Transfer Object)。
2)應用層(Application Layer)
主要負責獲取輸入,組裝上下文,做輸入校驗,調用領域層做業務處理,如果需要的話,發送消息通知。當然,層次是開放的,若有需要,應用層也可以直接訪問基礎實施層。
3)領域層(Domain Layer)
主要是封裝了核心業務邏輯,并通過領域服務(Domain Service)和領域對象(Entities)的函數對外部提供業務邏輯的計算和處理.
4)基礎實施層(Infrastructure Layer)
主要包含 Tunnel(數據通道)、Config 和 Common。這里我們使用 Tunnel 概念來對所有的數據來源進行抽象,這些數據來源可以是數據庫(MySQL,NoSql)、搜索引擎、文件系統、也可以是 SOA 服務等;Config 負責應用的配置;Common 是通用的工具類。
6.2. 擴展設計
對于只有一個業務的簡單場景,對擴展性的要求并不突出,這也是為什么擴展設計常被忽略的原因,因為我們大部分的系統都是從單一業務開始的。但是隨著業務場景越來越復雜,代碼里面開始出現大量的 if-else 邏輯。此時除了常規的策略模式以外,我們可以考慮在架構層面提供統一的擴展解決方案。
在擴展設計中,我們提煉出兩個重要的概念,一個是業務身份 ,另一個是擴展點 。
業務身份是指業務在系統唯一標識一個業務或者一個場景的標志 。在具體實現中,我們使用 BizCode 來表示業務身份,其中 BizCode 采用類似 Java 包名命名空間的方式。例如,我們可以用 “ali.tmall” 表示阿里天貓業務,用 “ali.tmall.car” 表示阿里天貓的汽車業務,而用 'ali.tmall.car.aftermarket' 代表這是阿里天貓的汽車業務的后市場場景。
每個業務或者場景都可以實現一個或多個擴展點(ExtensionPoint) ,也就是說一個業務身份加上一個擴展點,可以唯一地確定一個擴展實現(Extension)。而這個業務身份和擴展點的組合,我們將其稱之為擴展坐標(ExtensionCoordinate),如下圖所示。
這樣,通過業務身份+擴展點,我們就可以從框架層面實現對不同租戶,不同業務,不同場景的擴展定制了。整個阿里業務中臺正是基于這個思想,實現的多業務支撐的。
6.3. 規范設計
任何事物都是規則性和隨機性的組合。規范的意義就在于我們可以將規則性的東西固化下來,盡量減少隨心所欲帶來的復雜度,一致性可以降低系統復雜度。從命名到架構皆是如此,而架構本身就是一種規范和約束,破壞這個約束,也就破壞了架構。
COLA 制定了一些列的規范:包括組件(Module)結構、包(Package)結構、命名等。
比如對于組件,我們要求使用 COLA 的應用都應該遵循如下圖所示的組件劃分:
6.4. COLA 架構總覽
在架構思想上,COLA 主張像六邊形架構那樣,使用端口-適配器去解耦技術細節;主張像洋蔥圈架構那樣,以領域為核心,并通過依賴倒置反轉領域層的依賴方向。最終形成如下圖所示的組件關系。
換一個視角,從 COLA 應用處理響應一個請求的過程來看。COLA 使用了 CQRS 來分離命令和查詢的職責,使用擴展點和元數據來提升應用的擴展性。整個處理流程如下圖所示:
七、應用架構的核心
縱觀上面介紹的所有應用架構,我們可以發現一個共同點,就是“核心業務邏輯和技術細節分離 ”。
是的,六邊形架構、洋蔥圈架構、以及 COLA 架構的核心職責就是要做核心業務邏輯和技術細節的分離和解耦。
試想一下,業務邏輯和技術細節糅雜在一起的情況,所有的代碼都寫在 ServiceImpl 里面,前幾行代碼是做 validation 的事,接下來幾行是做 convert 的事,然后是幾行業務處理邏輯的代碼,穿插著,我們需要通過 RPC 或者 DAO 獲取更多的數據,拿到數據后,又是幾行 convert 的代碼,在接上一段業務邏輯代碼,然后還要落庫,發消息.....等等。
再簡單的業務,按照上面這種寫代碼的方式,都會變得復雜,難維護。
因此,我認為應用架構的核心使命就是要分離業務邏輯和技術細節。讓核心業務邏輯可以反映領域模型和領域應用,可以復用,可以很容易被看懂。讓技術細節在輔助實現業務功能的同時,可以被替換。