軟件架構設計學習總結(22):軟件架構——分層架構、事件驅動架構、微內核架構、微服務架構、基於空間的架構

分層架構 (Layered Architecture)

分層架構是最多見的架構,也被稱爲n層架構。多年以來,許多企業和公司都在他們的項目中使用這種架構,它已經幾乎成爲事實標準,所以被大多數架構師、開發者和軟件設計者所熟知。好比MVC。web

分層架構的一個特性就是 關注分離(separation of concerns) 。在層中的組件只負責本層的邏輯。組件的劃分很容易讓它們實現本身的角色和職責,也比較容易地開發,測試管理和維護。數據庫

咱們須要這樣的冗餘,即便業務層沒有處理業務規則,也要經過業務層來調用數據層,這叫 分層隔離 。對於某些功能,若是咱們從表現層直接訪問數據層,那麼數據層後續的任何變更都將影響到業務層和表現層。apache

注意分層的 開閉原則 。若是某層是關閉的,那麼每一個請求都要通過着一層。相反,若是該層是開放的,那麼請求能夠繞過這一層,直接到下一層。服務器

分層隔離有利於下降整個應用程序的複雜度。某些功能並不須要通過每一層,這時咱們須要根據開閉原則來簡化實現。微信

污水池反模式(architecture sinkhole anti-pattern)

分層架構是 SOLID原則 的通用架構,當咱們不肯定哪一種架構更合適的時候,分層架構將是一個很好的起點。咱們須要注意防止架構陷入 污水池反模式(architecture sinkhole anti-pattern) 。網絡

在這個模式中,請求流只是簡單的 穿過層次,不留一點雲彩,或者說只留下一陣⻘青煙。好比說界面層響應了一個得到數據的請求。響應層把這 個請求傳遞給了業務層,業務層也只是傳遞了這個請求到持久層,持久層對數據庫作簡單的SQL查詢得到用戶的數據。這個數據按照原理返回,不會有任何的二次處理,返回到界面上。架構

每一個分層架構或多或少均可能遇到這種場景。關鍵在於這樣的請求有多少。80-20原則能夠幫助你肯定架構是 否處於反污水模式。大概有百分之二十的請求僅僅是作簡單的穿越,百分之八十的請求會作一些業務邏輯操 做。然而,若是這個比例反過來,大部分的請求都是僅僅穿過層,不作邏輯操做。那麼開放一些架構層會比較好。不過因爲缺乏了層次隔離,項目會變得難以控制。併發

巨石應用(Monolith)

分層架構能夠演變爲 巨石應用(Monolith) ,致使代碼庫難以維護。app

將全部功能都部署在一個web容器中運行的系統就叫作巨石型應用。巨石型應用有不少好處:IDE都是爲開發單個應用設計的、容易測試——在本地就能夠啓動完整的系統、容易部署——直接打包爲一個完整的包,拷貝到web容器的某個目錄下便可運行。負載均衡

可是,上述的好處是有條件的:應用不那麼複雜。對於大規模的複雜應用,巨石型應用會顯得特別笨重:

  • 要修改一個地方就要將整個應用所有部署(PS:在不一樣的場景下優點也變成了劣勢);

  • 編譯時間過長;迴歸測試周期過長;

  • 開發效率下降等。

  • 巨石應用不利於更新技術框架,除非你願意將系統所有重寫(代價過高你願意老闆也不肯意)。

架構舉例

咱們看一下淘寶前幾年的架構的例子:

這是一個標準的分層的架構。每一層中又能夠詳細的分紅更細的層,好比服務層。

圍着着這個主架構還有一些外圍的產品。好比監控和審計。

Tips:

  • 不一樣的階段,不一樣的業務場景,不一樣的業務複雜度,不一樣的團隊,適合不一樣的分層。

  • 有些分層是兼容低端狀況(初創公司用起來也很美,還兼顧之後的發展和迭代),有些不兼容(團隊層次達不到,玩不轉)。

  • 分層將致使複雜度的上升。(博弈)

  • 注意接口和邊界。(否則白分)

事件驅動架構 (Event-Driven Architecture)

事件驅動架構(Event Driven Architecture)是一種流行的分佈式異步架構模式,用於建立可伸縮的應用程序。這種模式是自適應的,可用於小規模或者大規模的應用程序。它由高度解耦的,單一目的的事件處理組件組成,能夠異步地接收和處理事件。

它包括兩個主要的拓撲結構: 調停者拓撲(Mediator Topology) 和 代理者拓撲(Broker Topology) 。Mediator拓撲結構須要你在一個事件經過mediator時精心安排好幾個步驟,而broker拓撲結構無需mediator,而是由你串聯起幾個事件。這兩種拓撲架構的特徵和實現有很大的不一樣,因此你須要知道哪個適合你。

調停者拓撲(Mediator Topology)

Mediator拓撲結構適合有多個步驟的事件,須要安排處理層次。

例如購買一隻股票,首先會校驗這個交易,校驗股票交易是否符合各類規定,將它交給一個經紀人,計算佣金,最後確認交易。全部這些都安排好各個步驟的順序,決定它們是否串行仍是並行。

一般,架構主要包含4種組件,事件隊列(Event Queue)、調停者(Mediator)、事件通道(Event Channel)和事件處理器(Event Processor)。客戶端建立事件,並將其發送到事件隊列,調停者接收事件並將其傳遞給事件通道。事件通道將事件傳遞給事件處理器,事件最終由事件處理器處理完成。

事件流是這樣開始的: 客戶端發送一個事件到事件隊列(event queues)中,它用來將事件傳送給event mediator。Event mediator收到初始的事件後,會發送額外的一些異步事件給event channels來執行處理的每一個步驟。Event processors監聽event channels,接收事件並處理一些業務邏輯。

事件調停者不會處理也不知道任何業務邏輯,它只編排事件。事件調停者知道每種事件類型的必要步驟。業務邏輯或者處理髮生在事件處理器中,事件通道、消息隊列或者消息主題用於傳遞事件給事件處理器。事件處理器是自包含和獨立的,解耦於架構。理想狀況下,每種事件處理器應只負責處理一種事件類型。

這裏有兩種事件:初始事件和處理事件。Mediator會將初始事件編排成處理事件。它沒有具體的業務邏輯,只是一個協調者,負責將初始事件轉化成一個或者多個處理事件。

在事件驅動架構中有十幾個甚至幾百個事件隊列都很正常。模式自己沒有限定事件隊列的實現方式。它多是一個消息隊列,一個web service或者其它。

event channels 既能夠是消息隊列,也能夠是消息topic,大部分是消息topic,這樣能夠由多個消息處理器(event processor)處理同一個消息。

消息處理器包含實際的業務邏輯。每一個消息處理器都是自包含的,獨立的,高度解耦的,執行單一的任務。這種模式可能有一些變種。做爲架構師,你應該理解每一個實現的細節,確保這種解決方案適合你的需求。有一些開源的框架實現了這種架構,如Spring Integration, Apache Camel, 或者 Mule ESB。

代理者拓撲(Broker Topology)

喜歡 | 做者 韓陸 發佈於 2016年3月30日. 估計閱讀時間: 不到一分鐘 | 道AI風控、Serverless架構、EB級存儲引擎,盡在ArchSummit! 4 討論

分享到: 微博 微信 Facebook Twitter 有道雲筆記 郵件分享

稍後閱讀個人閱讀清單

【編者的話】本文來自Firat Atagun的《架構演化中的軟件設計原則》,文中給出了軟件架構演化過程當中出現的4種經典架構,就每種架構,分析了其主要特色並在幾個度量維度給出結論。在文章的最後,Firat Atagun給出了4種架構的多維對比。本文的完整演講稿是架構演化中的軟件設計原則。

1 分層架構

分層架構是最多見的架構,也被稱爲n層架構。多年以來,許多企業和公司都在他們的項目中使用這種架構,它已經幾乎成爲事實標準,所以被大多數架構師、開發者和軟件設計者所熟知。

分層架構中的層次和組件是水平方向的分層,每層扮演應用程序中特定的角色。根據需求和軟件複雜度,咱們能夠設計N層,但大多數應用程序使用3-4層。有太多層的設計會很糟糕,將致使複雜度的上升,由於咱們必須維護每一層。在傳統的分層架構中,分層包括表現層、業務或者服務層,以及數據訪問層。 表現層負責應用程序的用戶交互和用戶體驗(外觀和視覺)。一般咱們會使用數據傳輸對象(Data Transfer Object)將數據帶到這一層,而後使用視圖模型(View Model)渲染到客戶端。業務層接收請求並執行業務規則。數據訪問層負責操做各類類型的數據庫,每一個訪問數據庫的請求都要通過這一層。

分層無需知道其餘層如何去作,好比業務層無需知道數據訪問層是如何查詢數據庫的,相反,業務層在調用數據層的特定方法時,只需關注須要部分數據仍是所有數據。這就是咱們所說的關注點分離。這是很是強大的功能,每層負責其所負的責任。

分層架構中的核心概念是管理依賴。若是咱們使用依賴倒置原則和測試驅動開發(Test Driven Development),咱們的架構會有更好的健壯性。由於,咱們要保證全部可能的用例都有測試用例。

咱們須要這樣的冗餘,即便業務層沒有處理業務規則,也要經過業務層來調用數據層,這叫分層隔離。對於某些功能,若是咱們從表現層直接訪問數據層,那麼數據層後續的任何變更都將影響到業務層和表現層。

相關廠商內容

微信Android模塊化架構重構實踐 蘑菇街分佈式消息中間件Corgi的架構演進 Serverless架構:一條SQL到一個服務有多遠? 對抗複雜性,架構設計中可借鑑複用這些手段 阿里:風控場景的模型平臺架構設計

相關贊助商

ArchSummit深圳2017,7月7-8日,深圳·華僑城洲際酒店,精彩內容搶先看

分層架構中的一個重要的概念就是分層的開閉原則。若是某層是關閉的,那麼每一個請求都要通過着一層。相反,若是該層是開放的,那麼請求能夠繞過這一層,直接到下一層。

分層隔離有利於下降整個應用程序的複雜度。某些功能並不須要通過每一層,這時咱們須要根據開閉原則來簡化實現。

分層架構是SOLID原則的通用架構,當咱們不肯定哪一種架構更合適的時候,分層架構將是一個很好的起點。咱們須要注意防止架構陷入污水池反模式。這種反模式描述了請求通過分層,但沒作任何事或者只處理了不多的事。若是咱們的請求通過全部分層而沒有作任何事,這就是污水池反模式的徵兆。若是20%的請求只是通過各層,而80%的請求實際作事,這還好,若是這個比率不是這樣的,那麼咱們已經患上反模式綜合徵。

此外,分層架構能夠演變爲巨石應用(Monolith),致使代碼庫難以維護。

分層架構分析:

敏捷性:整體敏捷性是指對不斷變化的環境做出反應的能力。因爲其總體風格(Monolith)的性質,可能會變得難以應對經過全部層的變化,開發者須要注意依賴性和分層分離。

易於部署:大型應用程序的部署會是個麻煩。一個小要求,可能須要部署整個應用程序。若是能作好持續交付,可能會有所幫助。

可測試性:使用Mocking和Faking,每一層能夠獨立測試,所以測試上很容易。

性能:雖然分層應用程序可能表現良好,可是由於請求須要通過多個分層,可能會存在性能問題。

可伸縮性:由於耦合太緊以及總體風格(Monolith)的天生特質,很難對分層應用程序進行伸縮。然而,若是分層可以被構建爲獨立的部署,仍是能夠具有伸縮能力的。可是,這樣作的代價可能很昂貴。

易於開發:這種模式特別易於開發。許多企業採用這種模式。大多數開發者也都知道、瞭解,而且能夠輕鬆學習如何使用它。

2 事件驅動架構

事件驅動架構(Event Driven Architecture)是一種流行的分佈式異步架構模式,用於建立可伸縮的應用程序。這種模式是自適應的,可用於小規模或者大規模的應用程序。事件驅動架構能夠與調停者拓撲(Mediator Topology)或者代理者拓撲(Broker Topology)一塊兒使用。理解拓撲的差別,爲應用程序選擇正確的拓撲是必不可少的。

調停者拓撲

調停者拓撲須要編排多種事件。好比在交易系統中,每一個請求流程必須通過特定的步驟,如驗證、訂單、配送,以及通知買家等。在這些步驟中,有些能夠手動完成,有些能夠並行完成。

一般,架構主要包含4種組件,事件隊列(Event Queue)、調停者(Mediator)、事件通道(Event Channel)和事件處理器(Event Processor)。客戶端建立事件,並將其發送到事件隊列,調停者接收事件並將其傳遞給事件通道。事件通道將事件傳遞給事件處理器,事件最終由事件處理器處理完成。

事件調停者不會處理也不知道任何業務邏輯,它只編排事件。事件調停者知道每種事件類型的必要步驟。業務邏輯或者處理髮生在事件處理器中,事件通道、消息隊列或者消息主題用於傳遞事件給事件處理器。事件處理器是自包含和獨立的,解耦於架構。理想狀況下,每種事件處理器應只負責處理一種事件類型。

一般,企業服務總線、隊列或者集線器能夠用做事件調停者。正確選擇技術和實現可以下降風險。

代理者拓撲

不像調停者拓撲,代理者拓撲不使用任何集中的編排,它沒有中心的Mediator。而是在事件處理器之間使用簡單的隊列或者集線器,事件處理器知道處理事件的下一個事件處理器。全部的事件串聯起來經過一個輕量級的消息broker如RabbitMQ,ActiveMQ,HornetQ等。若是你的消息比較簡單,不須要從新編排,就可使用這種結構。

如圖所示,它包含兩個組件broker和 event processor。broker中的event channel能夠是消息隊列,消息topic或者它們的複合形式。每一個event processor負責處理事件,發佈新的事件。

舉例

在新浪微博的早期架構中,微博發佈使用同步推模式,用戶發表微博後系統會當即將這條微博插入到數據庫全部粉絲的訂閱列表中,當用戶量比較大時,特別是明星用戶發佈微博時,會引發大量的數據庫寫操做,超出數據庫負載,系統性能急劇降低,用戶響應延遲加重。

後來新浪微博改用異步推拉結合的模式,用戶發表微博後系統將微博寫入消息隊列後當即返回,用戶響應迅速,消息隊列消費者任務將微博推送給全部當前在線粉絲的訂閱列表中,非在線用戶登陸後再根據關注列表拉取微博訂閱列表。

Tips

因其分佈式和異步的性質,事件驅動架構的實現相對複雜,主要是因爲它的異步和分佈式特性。咱們須要面對不少問題,好比網絡分區、調停者失敗、從新鏈接邏輯等。因爲這是一個分佈式且異步的模式,若是你須要事務,那就麻煩了,你得須要一個事務協調器。分佈式系統中的事務很是難以管理,很難找到標準的工做單位模式。

一個考慮是這種模式對於單一的邏輯缺少原子事務。因此你須要將原子事務交給一個事件處理器執行,跨事件處理器的原子事務是很困難的。

最困難的設計之一是事件處理器的建立,維護和管理。事件一般有特殊的約定(數據值和格式)。

微內核架構 (Microkernel Architecture)

微內核架構(Microkernel architecture)模式也被稱爲插件架構(plugin architecture)模式。能夠用來實現基於產品的應用, 好比Eclipse,在微內核的基礎上添加一些插件,就能夠提供不一樣的產品,如C++, Java等。

微內核包含兩個組件: core system 和 plug-in modules。應用邏輯被分隔成核心繫統和插件模塊,能夠提供可擴展的,靈活的,特性隔離的功能。

這種模式很是適合桌面應用程序,可是也能夠在Web應用程序中使用。事實上,許多不一樣的架構模式能夠做爲整個系統的一個插件。對於產品型應用程序來講,若是咱們想將新特性和功能及時加入系統,微內核架構是一種不錯的選擇。

微內核的架構模式能夠嵌入到其它的架構模式之中。微內核架構經過插件還能夠提供逐步演化的功能和增量開發。因此若是你要開發基於產品的應用,微內核是不二選擇。

微服務架構(Microservices architecture)

儘管微服務的概念還至關新,但它確實已經快速地吸引了大量的眼球,以替代總體應用和麪向服務架構(SOA)。其中的一個核心概念是具有高可伸縮性、易於部署和交付的獨立部署單元(Separately Deployable Units)。最重要的概念是包含業務邏輯和處理流程的服務組件(Service Component)

無論你使用何種實現風格和拓撲,有幾個通用的核心概念應用在這種架構模式上。首先是分隔發佈單元(separately deployed units)。

如圖所示,每個微內核的組件都被分隔成一個獨立的單元。微服務包含 服務組件(service component )。不要考慮微內核的單個服務,而是最好考慮服務組件,從粒度上講它能夠是單一的模塊或者一個一個大的應用程序,表明單一功能(提供天氣預報或者圖片存儲)。

正確設計服務組件的粒度是一個很大的挑戰。

另外一個關鍵概念是微內核是分佈式的。這意味着服務組件多是遠程方法(經過JMS, AMQP, REST, SOAP, RMI......等等)。分佈式意味着這種模式能夠創建大規模的應用。

另外一個值得興奮的特性是它能夠從其它有問題的架構模式中演化出來,而不是直接建立出來等待問題發生。當你遇到一些沒法解決的問題,特別是互聯網企業的規模擴大時,是很好的引入微服務架構的時機。

通常會從兩個模式中演化:

  • 一種就是一開始就是總體的應用,全部的模塊都是緊耦合的。

  • 另一種是 面向服務的架構模式(SOA,service-oriented architecture pattern) 。

SOA不是很差,可是太昂貴了,很差理解和實現。

應用拆分

這張圖從三個維度歸納了一個系統的擴展過程:

  • x軸,水平復制,即在負載均衡服務器後增長多個web服務器;

  • z軸擴展,是對數據庫的擴展,即分庫分表(分庫是將關係緊密的表放在一臺數據庫服務器上,分表是由於一張表的數據太多,須要將一張表的數據經過hash放在不一樣的數據庫服務器上);

  • y軸擴展,是功能分解,將不一樣職能的模塊分紅不一樣的服務。

從y軸這個方向擴展,才能將巨型應用分解爲一組不一樣的服務,例如訂單管理中心、客戶信息管理中心、商品管理中心等等。

實現方式

有不少實現微服務的方式。最通用最流行的三個方式是:

  • API REST-based

  • applicaiton REST-based

  • 中心化的消息

API REST-based 適合網站提供小規模的,自包含的服務。不少互聯網網站都提供這樣的服務,好比OAuth2服務。

application REST-based不一樣於上面的架構,客戶端看到的是web界面或者富客戶端程序,而不是調用API。UI層獨立發佈,能夠訪問服務組件。

中心消息模式,它相似前面的模式,可是使用一個輕量級的消息broker取代RESTful的服務調用。這個輕量級的broker不會執行服務的編排,傳輸和路由,這和SOA不一樣,不要把它看做SOA的簡化版

內部服務之間的通訊

內部服務之間的通訊方式有兩種:基於HTTP協議的同步機制(REST、RPC);基於消息隊列的異步消息處理機制(AMQP-based message broker)。

Dubbo 是阿里巴巴開源的分佈式服務框架,屬於同步調用,當一個系統的服務太多時,須要一個註冊中心來處理服務發現問題,例如使用ZooKeeper這類配置服務器進行服務的地址管理:服務的發佈者要向ZooKeeper發送請求,將本身的服務地址和函數名稱等信息記錄在案;服務的調用者要知道服務的相關信息,具體的機器地址在ZooKeeper查詢獲得。這種同步的調用機制足夠直觀簡單,只是沒有「訂閱——推送」機制。

AMQP-based的表明系統是 Kafka 、 RabbitMQ 等。這類分佈式消息處理系統將訂閱者和消費者解耦合,消息的生產者不須要消費者一直在線;消息的生產者只須要把消息發送給消息代理,所以也不須要服務發現機制。

兩種通訊機制都有各自的優勢和缺點,實際中的系統常常包含兩種通訊機制。例如,在分佈式數據管理中,就須要同時用到同步HTTP機制和異步消息處理機制。

微服務架構解決了無架構的總體編碼的應用的問題以及SOA的問題。同時它還能夠提供實時的產品發佈。它是一個分佈式架構,也會有上面分佈式的問題。

基於空間的架構 (Space-Based Architecture)

基於空間的架構有時候也被成爲基於雲的架構。

大部分的基於web的應用的業務流都是同樣的。 客戶端的請求發送給web服務器,而後是應用服務器,最後是數據庫服務器。對於用戶很小時不會有問題,可是負載增大時就會遇到瓶頸(想一想搶火車票)。首先是web服務器撐不住,web服務器能撐住應用服務器又不行,而後是數據庫服務器。一般解決方案是增長web服務器,便宜,簡單,但不少狀況下負載會傳遞給應用服務器,而後傳遞給數據庫服務器。有時候增長數據庫服務器也沒有辦法,由於數據庫也有鎖,有事務的限制。

基於空間的架構用來解決規模和併發的問題。

基於空間的架構最小化限制應用規模的影響。這個模式來自於tuple space, 分佈式共享內存想法。要想大規模,就要移除中心數據庫的限制,使用可複製的內存網格。應用數據保存在全部活動的處理單元的內存中,處理單元根據應用規模能夠加入和移除。由於沒有中心數據庫,因此數據庫的瓶頸能夠解決。

這種模式有兩個組件: 處理單元processing unit 和 虛擬化中間件virtualized middleware 。

處理單元包含應用程序。小的應用程序可使用一個處理單元,大的應用程序能夠被分隔成幾個處理單元。處理單元還包括數據網格。

虛擬化中間件負責管理和通訊。處理數據的同步和請求。

基於空間的架構是一個複雜而昂貴的模式。對於小型的負載可變的web應用很適合,可是對於大型的關係型數據庫應用不是太適合。

比較

相關文章
相關標籤/搜索