高並發系統設計(二):架構分層:我們為什么一定要這么做?


在系統從0到1的階段,為了讓系統快速上線,我們通常是不考慮分層的。但是隨着業務越來越復雜,大量的代碼糾纏在一起,會出現邏輯不清晰、各模塊相互依賴、代碼擴展性差、改動一處就牽一發而動全身等問題。

我們常見的設計方式如MVC分層、ISO七層模型、Linux系統分層、Mysql分層、PHP分層等等...

分層有什么好處

  1. 分層的設計可以簡化系統設計,讓不同的人專注做某一層次的事情。想象一下,如果你要設計一款網絡程序卻沒有分層,該是一件多么痛苦的事情。
  2. 分層之后可以做到很高的復用。比如,我們在設計系統A的時候,發現某一層具有一定的通用性,那么我們可以把它抽取獨立出來,在設計系統B的時候使用起來,這樣可以減少研發周期,提升研發的效率。
  3. 分層架構可以讓我們更容易做橫向擴展。如果系統沒有分層,當流量增加時我們需要針對整體系統來做擴展。但是,如果我們按照上面提到的三層架構將系統分層后,那么我們就可以針對具體的問題來做細致的擴展。比如說,業務邏輯里面包含有比較復雜的計算,導致CPU成為性能的瓶頸,那這樣就可以把邏輯層單獨抽取出來獨立部署,然后只對邏輯層來做擴展,這相比於針對整體系統擴展所付出的代價就要小的多了。

如何來做系統分層

參照阿里發布的《阿里巴巴Java開發手冊v1.4.0(詳盡版)》,我們可以將原先的三層架構細化成下面的樣子:

 

 

 

  • 終端顯示層:各端模板渲染並執行顯示的層。當前主要是 Velocity 渲染,JS 渲染, JSP 渲染,移動端展示等。
  • 開放接口層:將Service層方法封裝成開放接口,同時進行網關安全控制和流量控制等。
  • Web層:主要是對訪問控制進行轉發,各類基本參數校驗,或者不復用的業務簡單處理等。
  • Service層:業務邏輯層。
  • Manager 層:通用業務處理層。這一層主要有兩個作用,其一,你可以將原先Service層的一些通用能力下沉到這一層,比如與緩存和存儲交互策略,中間件的接入;其二,你也可以在這一層封裝對第三方接口的調用,比如調用支付服務,調用審核服務等。
  • DAO層:數據訪問層,與底層 MySQL、Oracle、Hbase 等進行數據交互。
  • 外部接口或第三方平台:包括其它部門 RPC 開放接口,基礎平台,其它公司的 HTTP 接口。

在這個分層架構中主要增加了Manager層,它與Service層的關系是:Manager層提供原子的服務接口,Service層負責依據業務邏輯來編排原子接口。

以上面的例子來說,Manager層提供創建用戶和獲取用戶信息的接口,而Service層負責將這兩個接口組裝起來。這樣就把原先散布在表現層的業務邏輯都統一到了Service層,每一層的邊界就非常清晰了。

除此之外,分層架構需要考慮的另一個因素,是層次之間一定是相鄰層互相依賴,數據的流轉也只能在相鄰的兩層之間流轉。

我們還是以三層架構為例,數據從表示層進入之后一定要流轉到邏輯層,做業務邏輯處理,然后流轉到數據訪問層來和數據庫交互。那么你可能會問:“如果業務邏輯很簡單的話可不可以從表示層直接到數據訪問層,甚至直接讀數據庫呢?”

其實從功能上是可以的,但是從長遠的架構設計考慮,這樣會造成層級調用的混亂,比方說如果表示層或者業務層可以直接操作數據庫,那么一旦數據庫地址發生變更,你就需要在多個層次做更改,這樣就失去了分層的意義,並且對於后面的維護或者重構都會是災難性的。

分層架構的不足

任何事物都不可能是盡善盡美的,分層架構雖有優勢也會有缺陷,它最主要的一個缺陷就是增加了代碼的復雜度。

這是顯而易見的嘛,明明可以在接收到請求后就可以直接查詢數據庫獲得結果,卻偏偏要在中間插入多個層次,並且有可能每個層次只是簡單地做數據的傳遞。有時增加一個小小的需求也需要更改所有層次上的代碼,看起來增加了開發的成本,並且從調試上來看也增加了復雜度,原本如果直接訪問數據庫我只需要調試一個方法,現在我卻要調試多個層次的多個方法。

另外一個可能的缺陷是,如果我們把每個層次獨立部署,層次間通過網絡來交互,那么多層的架構在性能上會有損耗。這也是為什么服務化架構性能要比單體架構略差的原因。

那我們是否要選擇分層的架構呢?答案當然是肯定的。

你要知道,任何的方案架構都是有優勢有缺陷的,分層架構固然會增加系統復雜度,也可能會有性能的損耗,但是相比於它能帶給我們的好處來說,這些都是可以接受的,或者可以通過其它的方案解決的。我們在做決策的時候切不可以偏概全。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM