架構
什麼是架構?數據庫
關於架構這個概念很難給出一個明確的定義,也沒有一個標準的定義。後端
硬是要給一個概述,我認爲架構就是對系統中的實體以及實體之間的關係所進行的抽象描述。緩存
架構始於建築,是由於人類發展(原始人自給自足住在樹上,也就不須要架構),分工協做的須要,將目標系統按某個原則進行切分,切分的原則,是要便於不一樣的角色進行並行工做。安全
爲何須要架構?服務器
有系統的地方就須要架構,大到航空飛機,小到一個電商系統裏面的一個功能組件都須要設計和架構。網絡
我很喜歡《系統架構:複雜系統的產品設計與開發》裏面的一句話:結構良好的創造活動要優於毫無結構的創造活動。架構
與之相對應的,如今不少敏捷思想提倡 no design,只要 work 就好。期待好的架構能夠在迭代中天然涌現。這個想法有點太理想化了,在現實中,只要能 work 的代碼,工程師是不多有動力去重構和優化的。框架
架構師的職責運維
做爲架構師,咱們最重要的價值應該是「化繁爲簡」。但凡讓事情變得更復雜,讓系統變得更晦澀難懂的架構都是值得商榷的。分佈式
架構師的工做就是要努力訓練本身的思惟,用它去理解複雜的系統,經過合理的分解和抽象,使哪些系統再也不那麼難懂。咱們應該努力構建易懂的架構,使得在系統上工做的其餘人員(例如設計者、實現者、操做員等)能夠較爲容易地理解這個系統。
軟件架構
軟件架構是一個系統的草圖。軟件架構描述的對象是直接構成系統的抽象組件。各個組件之間的鏈接則明確和相對細緻地描述組件之間的通訊。在實現階段,這些抽象組件被細化爲實際的組件,好比具體某個類或者對象。在面向對象領域中,組件之間的鏈接一般用接口來實現。
軟件架構爲軟件系統提供了一個結構、行爲和屬性的高級抽象,由構件的描述、構件的相互做用、指導構件集成的模式以及這些模式的約束組成。軟件架構不只顯示了軟件需求和軟件結構之間的對應關係,並且指定了整個軟件系統的組織和拓撲結構,提供了一些設計決策的基本原理。
軟件架構的核心價值應該只圍繞一個核心命題:控制複雜性。他並不意味着某個特定的分層結構,某個特定的方法論(貧血、DDD 等)。
軟件架構分類
在介紹應用架構以前,咱們先來看一下軟件架構的分類。
隨着互聯網的發展,如今的系統要支撐數億人同時在線購物、通訊、娛樂的須要,相應的軟件體系結構也變得愈來愈複雜。軟件架構的含義也變得更加寬泛,咱們不能簡單地用一個軟件架構來指代全部的軟件架構工做。按照我我的理解,我將軟件架構劃分爲:
業務架構:由業務架構師負責,也能夠稱爲業務領域專家、行業專家。業務架構屬於頂層設計,其對業務的定義和劃分會影響組織結構和技術架構。例如,阿里巴巴在沒有中臺部門以前,每一個業務部門的技術架構都是煙囪式的,淘寶、天貓、飛豬、1688 等各有一套體系結構。然後,成立了共享平臺事業部,打通了帳號、商品、訂單等體系,讓商業基礎實施的複用成爲可能。
應用架構:由應用架構師負責,他須要根據業務場景的須要,設計應用的層次結構,制定應用規範、定義接口和數據交互協議等。並儘可能將應用的複雜度控制在一個能夠接受的水平,從而在快速的支撐業務發展的同時,在保證系統的可用性和可維護性的同時,確保應用知足非功能屬性要求(性能、安全、穩定性等)。
分佈式系統架構:分佈式系統基本是稍具規模業務的必選項。它須要解決服務器負載,分佈式服務的註冊和發現,消息系統,緩存系統,分佈式數據庫等問題,同時架構師要在 CAP(Consistency,Availability,Partition tolerance)之間進行權衡。
數據架構:對於規模大一些的公司,數據治理是一個很重要的課題。如何對數據收集、數據處理提供統一的服務和標準,是數據架構須要關注的問題。其目的就是統一數據定義規範,標準化數據表達,造成有效易維護的數據資產,搭建統一的大數據處理平臺,造成數據使用閉環。
物理架構:物理架構關注軟件元件是如何放到硬件上的,包括機房搭建、網絡拓撲結構,網絡分流器、代理服務器、Web服務器、應用服務器、報表服務器、整合服務器、存儲服務器和主機等。
運維架構:負責運維繫統的規劃、選型、部署上線,創建規範化的運維體系。
典型應用架構
分層架構
分層是一種常見的根據系統中的角色(職責拆分)和組織代碼單元的常規實踐。常見的分層結構以下圖所示:
CQRS
CQS(Command Query Separation,命令查詢分離),最先來自於 Betrand Meyer(Eiffel 語言之父,OCP 提出者)提出的概念。其基本思想在於,任何一個對象的方法能夠分爲兩大類:
- 命令(Command): 不返回任何結果(void),但會改變對象的狀態。
- 查詢(Query): 返回結果,可是不會改變對象的狀態,對系統沒有反作用。
六邊形架構
六邊形架構是 Alistair Cockburn 在 2005 年提出,解決了傳統的分層架構所帶來的問題,實際上它也是一種分層架構,只不過不是上下,而是變成了內部和外部(以下圖所示)。
六邊形架構又稱爲端口-適配器架構,這個名字更容易理解。六邊形架構將系統分爲內部(內部六邊形)和外部,內部表明了應用的業務邏輯,外部表明應用的驅動邏輯、基礎設施或其餘應用。
適配器分爲兩種類型(以下圖所示),左側表明 UI 的適配器被稱爲主動適配器(Driving Adapters),由於是它們發起了對應用的一些操做。而右側表示和後端工具連接的適配器,被稱爲被動適配器(Driven Adapters),由於它們只會對主適配器的操做做出響應。
洋蔥圈架構
洋蔥架構與六邊形架構有着相同的思路,它們都經過編寫適配器代碼將應用核心從對基礎設施的關注中解放出來,避免基礎設施代碼滲透到應用核心之中。這樣應用使用的工具和傳達機制均可以輕鬆地替換,能夠必定程度地避免技術、工具或者供應商鎖定。
不一樣的是洋蔥架構還告訴咱們,企業應用中存在着不止兩個層次,它在業務邏輯中加入了一些在領域驅動設計的過程當中被識別出來的層次(Application,Domain Service,Domain model,Infrastructure等)。
另外,它還有着脫離真實基礎設施和傳達機制應用仍然能夠運行的便利,這樣可使用 mock 代替它們方便測試。
在洋蔥架構中,明確規定了依賴的方向:
- 外層依賴內層;
- 內層對外層無感知。
COLA 應用架構
COLA 架構是我團隊自主研發的應用架構,目前已經開源。在 COLA 的設計中,咱們充分汲取了經典架構的優秀思想。除此以外,咱們補充了規範設計和擴展設計,而且使用 Archetype 的方式,將架構固化下來,以即可以快速的在開發中使用。
分層設計
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 是通用的工具類。
擴展設計
對於只有一個業務的簡單場景,對擴展性的要求並不突出,這也是爲何擴展設計常被忽略的緣由,由於咱們大部分的系統都是從單一業務開始的。可是隨着業務場景愈來愈複雜,代碼裏面開始出現大量的if-else邏輯。此時除了常規的策略模式之外,咱們能夠考慮在架構層面提供統一的擴展解決方案。
在擴展設計中,咱們提煉出兩個重要的概念,一個是業務身份,另外一個是擴展點。
業務身份是指業務在系統惟一標識一個業務或者一個場景的標誌。在具體實現中,咱們使用 BizCode 來表示業務身份,其中 BizCode 採用相似 Java 包名命名空間的方式。例如,咱們能夠用「ali.tmall」表示阿里天貓業務,用「ali.tmall.car」 表示阿里天貓的汽車業務,而用"ali.tmall.car.aftermarket"表明這是阿里天貓的汽車業務的後市場場景。
每一個業務或者場景均可以實現一個或多個擴展點(ExtensionPoint),也就是說一個業務身份加上一個擴展點,能夠惟一地肯定一個擴展實現(Extension)。而這個業務身份和擴展點的組合,咱們將其稱之爲擴展座標(ExtensionCoordinate),以下圖所示。
這樣,經過業務身份+擴展點,咱們就能夠從框架層面實現對不一樣租戶,不一樣業務,不一樣場景的擴展定製了。整個阿里業務中臺正是基於這個思想,實現的多業務支撐的。
規範設計
任何事物都是規則性和隨機性的組合。規範的意義就在於咱們能夠將規則性的東西固化下來,儘可能減小爲所欲爲帶來的複雜度,一致性能夠下降系統複雜度。從命名到架構皆是如此,而架構自己就是一種規範和約束,破壞這個約束,也就破壞了架構。
COLA 制定了一些列的規範:包括組件(Module)結構、包(Package)結構、命名等。
好比對於組件,咱們要求使用 COLA 的應用都應該遵循以下圖所示的組件劃分:
COLA 架構總覽
在架構思想上,COLA 主張像六邊形架構那樣,使用端口-適配器去解耦技術細節;主張像洋蔥圈架構那樣,以領域爲核心,並經過依賴倒置反轉領域層的依賴方向。最終造成以下圖所示的組件關係。
換一個視角,從 COLA 應用處理響應一個請求的過程來看。COLA 使用了 CQRS 來分離命令和查詢的職責,使用擴展點和元數據來提高應用的擴展性。整個處理流程以下圖所示:
應用架構的核心
縱觀上面介紹的全部應用架構,咱們能夠發現一個共同點,就是「核心業務邏輯和技術細節分離」。
是的,六邊形架構、洋蔥圈架構、以及 COLA 架構的核心職責就是要作核心業務邏輯和技術細節的分離和解耦。
試想一下,業務邏輯和技術細節糅雜在一塊兒的狀況,全部的代碼都寫在 ServiceImpl 裏面,前幾行代碼是作 validation 的事,接下來幾行是作 convert 的事,而後是幾行業務處理邏輯的代碼,穿插着,咱們須要經過 RPC 或者 DAO 獲取更多的數據,拿到數據後,又是幾行 convert 的代碼,再接上一段業務邏輯代碼,而後還要落庫,發消息.....等等。
再簡單的業務,按照上面這種寫代碼的方式,都會變得複雜,難維護。
所以,我認爲應用架構的核心使命就是要分離業務邏輯和技術細節。讓核心業務邏輯能夠反映領域模型和領域應用,能夠複用,能夠很容易被看懂。讓技術細節在輔助實現業務功能的同時,能夠被替換。
最後咱們發現,應用架構的道就是:「讓上帝的歸上帝,凱撒的歸凱撒。」
做者 | 張建飛 阿里巴巴高級技術專家
本文爲阿里雲原創內容,未經容許不得轉載。