淺談「架構設計演化」

  • 2019 年 11 月 10 日
  • 筆記

1. 單體架構

單體架構,是指由一台或多台電腦組成中心節點。將數據集中存儲於這個中心節點中,並且整個系統的所有業務功能也均在此集中處理。也就是說,在這種架構下,每個終端或客戶端機器僅僅負責數據的錄入和輸出,而數據的存儲與控制處理完全交由單體系統來完成。

01

特點:「三集中」

  • 業務集中 業務集中,指的是所有業務都統一處理。這樣做的好處是,業務較較容易做到規範、也比較容易被監管,進而控制風險。在很多傳統金融企業中,這樣的架構設計頗為常見。
  • 計算集中 計算集中,指的是所有對數據的加工處理邏輯,都是集中完成的。當然,這也是後來這種架構方式,飽受爭議之處。隨著業務規模的增加,對計算能力要求突增,這種計算集中的方式較難做到擴展。
  • 數據集中 數據集中,指的是所有相關數據都統一存儲,集中訪問。

02

主要痛點

  • 研發成本高 因為是單體應用,即使應用間存在功能重疊,也很難實現共享。一般不存在業務系統間的互相調用,使用什麼功能就本地開發完成,不依賴其他應用。當有頻繁的需求變更時,需要重新編碼、測試,完成開發全流程,很難做到快速迭代。因對現在的快速業務創新及敏捷交付的需求,很難滿足。
  • 維護困難 這類系統一般是是通過鏈條狀的本地調用完成,往往是由一個人或團隊負責開發和維護。隨著業務的發展和需求變化,本地程式碼在不斷的迭代和變更,最後形成了一個個垂直的功能孤島,只有原來的開發者才理解介面調用關係和功能需求,一旦原有的開發者離職或者調到其他項目組,這些功能模組的運維就會變得非常困難。隨著業務的發展和功能膨脹,這種架構很容易發生腐化現象。
  • 單點故障 這類設計的可靠性差,存在單點故障風險。如發生某個應用BUG,可能會波及整個系統的使用,造成全局性的影響。
  • 擴展性差 可伸縮性差:水平擴展只能基於整個系統進行擴展,無法針對某一個功能模組按需擴展。

2. 分離架構

為了應對傳統單體架構的問題,一般會採用拆分的策略。其核心就是降低軟體的複雜性,減少開發工作量,從而降低開發成本,提高軟體生產率。"分而治之"的結論,把複雜的問題分解為很多容易解決的小問題,原來的問題也就容易解決。

01

拆分方式

針對單體的拆分,可以遵從不同的邏輯及角度,

  • 業務角度 從業務角度出發,按照不同的思路和粒度來拆分軟體系統,就會得到不同的架構。
  1. 面向流程拆分:將整個業務流程拆分為幾個階段,每個階段作為一部分。
  2. 面向服務拆分:將系統提供的服務拆分,每個服務作為一部分。
  3. 面向功能拆分:將系統提供的功能拆分,每個功能作為一部分。 理解這三種思路的關鍵就在於如何理解"流程"、"服務"、"功能"三者的聯繫和區別。從範圍上來看,從大到小依次為:流程 > 服務 > 功能。
  • 技術角度 按照其實現,梳理和抽象出核心應用、公共應用,並作為獨立模組存在。其中分層架構就是很常見的架構模式。按照分層架構進行設計時,根據不同的劃分維度和對象,可以得到多種不同的分層架構。例如典型的C/S架構、B/S架構,其劃分的對象是整個業務系統,劃分的維度是用戶交互,即將和用戶交互的部分獨立為一層,支撐用戶交互的後台作為另外一層。

02

拆分原則:耦合與內聚

拆分出來的部分,可稱為子系統或模組,其應完成一個相對對立的功能,並且與其他子系統/模組之間的關係很簡單。其獨立性是模組化、抽象、資訊隱藏和局部化概念的直接結果,具有獨立模組的軟體容易開發、測試和維護。其獨立性通過兩項品質標準來衡量:耦合和內聚。

  • 耦合 衡量不同模組間相互依賴的緊密程度。也叫塊間聯繫。它是對一個軟體結構內不同模組之間互連程度的度量。它取決於各個模組之間介面的複雜程度、進入或訪問一個模組的點以及哪些資訊通過介面傳遞。在設計上,應該追求「低耦合」,即拆分單元之間應該是業務隔離性比較大的,相互依賴度不高。
  • 內聚 衡量一個模組內部各元素彼此結合的緊密程度。在設計上,需要追求「高內聚」,即劃分單元的業務邊界清晰,其內部的業務相關性很高、依賴性很高的。

03

主要痛點

  • 研發成本高 這種方式,依然存在程式碼到處拷貝的問題。為了實現某單一功能(例如資料庫訪問),不得不在各處自己來實現。這無形中導致了程式碼的拷貝。
  • 複雜度擴散 因各部分獨立實現,當面臨同一技術問題時,不得不都要去考慮。例如隨著數據量增大、並發訪問越來越高,用戶的資料庫訪問成為瓶頸。此時可考慮通過增加快取來降低讀壓力,對於這一架構上的調整,各業務線都需要關注其導致的複雜性。
  • 業務耦合度高 如業務系統間復用了部分程式碼,則如果業務A需要升級,業務B將不得不面臨被動升級的窘境。雖然可以通過拷貝程式碼方式解決,但又會造成程式碼冗餘等問題。
  • 故障隔離性差 如某業務系統出現問題,將很有可能會影響其關聯調用的其他業務系統,進而導致更多的業務線受影響。此外,從資料庫層面也存在類似問題,因各業務系統復用同一資料庫,當某性能較差的語句拖垮整個資料庫時,影響的可能是所有業務線。 上述問題的核心是沒有獨立的服務層。

3. 服務化(SOA)

為應對上述的問題,可將業務功能都獨立成服務。服務就意味著要對外提供開放的能力,當其他系統需要使用這項功能時,無須訂製化開發,直接引用即可。這種架構方式,可簡稱為SOA。SOA的全稱是Service Oriented Architecture,中文翻譯為"面向服務的架構"。SOA的出現,解決了企業內部多種業務系統的整合,這些系統可能異構、實現技術不同,但均可通過服務化完成整合,提高了業務系統的建設效率。

01

SOA特性

  • 面向服務的分散式計算
  • 服務間鬆散耦合
  • 支援服務的組裝
  • 服務註冊與自動發現
  • 以服務契約方式定義服務交互方式

02

SOA難點:松耦合

松耦合的目的是減少各個服務間的依賴和互相影響。因為採用 SOA 架構後,各個服務是相互獨立運行的,甚至都不清楚某個服務到底有多少對其他服務的依賴。如果做不到松耦合,某個服務一升級,依賴它的其他服務全部故障,這樣肯定是無法滿足業務需求的。但實際上真正做到松耦合併沒有那麼容易,要做到完全後向兼容,是一項複雜的任務。

03

SOA模式

  • 中心化(ESB模式) ESB的全稱是Enterprise Service Bus,中文翻譯為"企業服務匯流排"。ESB將企業中各個不同的服務連接在一起。因為各個獨立的服務是異構的,如果沒有統一的標準,則各個異構系統對外提供的介面是各式各樣的。SOA使用ESB來屏蔽異構系統對外提供各種不同的介面方式,以此來達到服務間高效的互聯互通。ESB這樣一個中心服務匯流排,提供了對各種技術介面(HTTP、Socket、JMS、JDBC等)的適配接入、數據格式轉換、數據裁剪、服務請求路由等功能。核心目的是讓企業客戶能基於這些SOA的產品實現系統間的互聯互通,同時提高開發集成效率,更快地實現SOA項目的落地。這一架構解決的根本訴求是實現異構系統之間的交互。
  • 去中心化 去中心化除了對SOA特性的實現和滿足外,相比"中心化"的不同主要就是服務提供者和服務調用者之間在進行服務交互時無需通過任何服務路由中介,避免因為"中心點"帶來的平台難擴展的問題及潛在的雪崩風險。但對於不同技術介面的支援、數據格式轉換、服務動態路由等功能沒有前者好,更多需要依靠服務應用的編寫來滿足這樣的需求。

對比兩者

  • 傳統ESB模式的服務調用方式是,每一次服務的調用者要向伺服器提供者進行服務交互請求時都必須通過中心的ESB來進行路由。經過服務匯流排路由過的服務交互,共出現4次網路會話創建和數據傳輸。而通過"去中心化"服務架構中的服務交互,一次服務的調用只有2次網路會話創建和數據傳輸,網路開銷降低一半。從邏輯上看,所有服務調用都通過服務匯流排,服務匯流排的訪問和計算壓力都會非常大。另外,所有業務都通過服務匯流排的方式,則服務調用量比較大,所需的網路頻寬要求非常高,甚至會出現超過目前網路設備的能力範圍。
  • "中心化"架構可能給平台帶來災難性的"雪崩"效應。且一旦遇到雪崩之後,故障恢復的時間和成本都非常高昂。正因為雪崩隱患存在,某種程度上束縛了中心化服務框架的平台擴展能力。也就是說,增加中心點企業服務匯流排實例的節點數量,並不能線性擴展平台的服務能力。"去中心化"服務框架可以避免因為個別問題波及整個平台的業務受影響,最多也只是部分服務出現問題,就算出現問題也更容易定位問題和故障恢復。

4. 微服務

微服務架構,是近些年來頗為流行的一個架構方式。從我來看,它更多的是服務化適應互聯網化的產物,而不是取代服務化。下述內容摘自極客時間-李運華的課程《從0開始學架構》。

01

對比:SOA vs 微服務

  • 服務粒度 整體上來說,SOA的服務粒度要粗一些,而微服務的服務粒度要細一些。
  • 服務通訊 SOA採用了ESB作為服務間通訊的關鍵組件,負責服務定義、服務路由、消息轉換、消息傳遞,總體上是重量級的實現。微服務推薦使用統一的協議和格式,例如,RESTful協議、RPC協議,無須ESB這樣的重量級實現。
  • 服務交付 SOA對服務的交付並沒有特殊要求,因為SOA更多考慮的是兼容已有的系統;微服務的架構理念要求"快速交付",相應地要求採取自動化測試、持續集成、自動化部署等敏捷開發相關的最佳實踐。如果沒有這些基礎能力支撐,就難以達到快速交付的要求,部署的成本呈指數上升。
  • 應用場景 SOA更加適合於龐大、複雜、異構的企業級系統,這也是SOA誕生的背景。這類系統的典型特徵就是歷時間久、技術棧不同、來源各異,無法大規模優化或重構。因為成本和影響太大,只能採用兼容的方式進行處理。微服務更加適合於快速、輕量級、基於Web的互聯網系統,這類系統業務變化快,需要快速嘗試、快速交付;同時基本都是基於Web,雖然開發技術可能差異很大,但對外介面基本都是提供HTTP RESTful風格的介面。

02

微服務特點

  • 分散式服務組成的系統
  • 按照業務而不是技術來劃分組織
  • 做有生命的產品而不是項目
  • 智慧化服務端點與傻瓜式服務編排
  • 自動化運維
  • 系統容錯
  • 服務快速演化

03

"微服務化"帶來的問題

  • 服務管控 在分散式服務體系下,服務鏈路跟蹤、鏈路分析、實時業務指標的監控等問題,也都是實現微服務架構時一定會面臨的問題,擴大到更大範圍就是整體服務平台的管控能力。
  • 分散式事務 需要針對業務的需求在事務一致性和性能間做好平衡,一套穩定、成熟的分散式事務解決方案也是構建微服務框架首先要考慮的技術問題。
  • 自動化運維 微服務化後,較之前的部署方式,從伺服器的數量以及服務交互複雜程度上都上升一個數量級,原有運維工具和平台是否能夠支撐需要好好考慮。
  • 服務設計 微服務中服務邊界的劃分一定是從業務的維度,以什麼樣的服務顆粒度定義服務?以什麼樣數據模型支撐服務能力的線性擴展?如何設計服務具有很好的業務前瞻性?
  • 組織架構 服務強調持續的演變,需要組建對應的組織或者對現有的組織架構進行調整,圍繞以服務為中心的持續運營,這對很多企業原有的資訊中心架構師不小的衝擊。

04

微服務陷阱

  • 服務劃分過細,服務間關係複雜 服務劃分過細,單個服務的複雜度確實下降了,但整個系統的複雜度卻上升了,因為微服務將系統內的複雜度轉移為系統間的複雜度了。從理論的角度來計算,n個服務的複雜度是n×(n-1)/2,整體系統的複雜度是隨著微服務數量的增加呈指數級增加的。
  • 服務數量太多,團隊效率急劇下降 微服務的"微"字,本身就是一個陷阱,將服務拆分得很細。這樣做給工作效率帶來了明顯的影響。一個簡單的需求開發就需要涉及多個微服務。無論是設計、開發、測試、部署,都需要工程師不停地在不同的服務間切換。
  • 調用鏈太長,性能下降 由於微服務之間都是通過HTTP或者RPC調用的,每次調用必須經過網路。在很多高性能業務場景下是難以滿足需求的。為了支撐業務請求,可能需要大幅增加硬體,這就導致了硬體成本的大幅上升。
  • 調用鏈太長,問題定位困難 系統拆分為微服務後,一次用戶請求需要多個微服務協同處理,任意微服務的故障都將導致整個業務失敗。然而由於微服務數量較多,且故障存在擴散現象,快速定位到底是哪個微服務故障是一件複雜的事情。
  • 沒有自動化支撐,無法快速交付 如果沒有相應的自動化系統進行支撐,都是靠人工去操作,那麼微服務不但達不到快速交付的目的,甚至還不如一個大而全的系統效率高。
  • 沒有服務治理,微服務數量多了後管理混亂 隨著微服務種類和數量越來越多,如果沒有服務治理系統進行支撐,微服務提倡的輕量化就會變成問題。如果以上場景都依賴人工去管理,整個系統將陷入一片混亂,最終的解決方案必須依賴自動化的服務管理系統。

5. 發展趨勢

01

領域驅動設計

領域驅動設計,簡稱DDD(Domain-Driven Design)。DDD是用來解決負責業務場景的。如果是簡單業務場景,可使用簡單的事務腳本解決;但對於複雜業務場景,這種方式就不再適用。因為一旦業務變得複雜,事務腳本就很難應對,容易造成程式碼的「一鍋粥」,系統的腐化速度和複雜性呈指數級上升。目前比較有效的治理辦法就是領域建模,因為領域模型是面向對象的,在封裝業務邏輯的同時,提升了對象的內聚性和重用性,因為使用了通用語言,使得隱藏的業務邏輯得到顯性化表達,使得複雜性治理成為可能。

02

業務服務平台

業務服務中台,其本質是服務化的延伸。從早期的」API as Service」,過渡到」 Product as Service」乃至」 Solution as Service」。方式上仍然是通過拆分業務解決系統的複雜性,通過服務共享來提供可重用性,通過服務化來達到業務支援的敏捷性;通過統一的數據架構來消除數據交互的屏障。其核心在於業務支援能力的構建,重點是在於提高業務效率,提升業務創新力。

  • 從設計層面,主要是要遵循面向對象的分析和設計的方法。
  • 從運營層面,服務中心應該是一個完整的業務模型,要有數據運營和業務整合的價值。
  • 從工程層面,服務中心是基於分散式架構,解決了在大規模應用上的問題