概述#

沒有人能告訴你該使用哪一種架構風格——選擇取決於組織內部的眾多因素和所建構的軟體類型。選擇架構風格是對 architecture characteristics 的 trade-offs、domain 考量、策略目標等多方面分析思考的最終結果。

不過,確實存在一些圍繞選擇適當架構風格的通用建議。

架構的「時尚」變遷(Shifting “Fashion”)#

偏好的架構風格會隨時間推移而改變,驅動因素包括:

  • 過去的觀察與痛點:新架構設計通常反映了過去架構風格的特定缺陷。例如架構師在經歷了重用導向架構的負面 trade-offs 後,重新思考了程式碼重用的意義
  • 生態系統的變化:軟體開發生態系統不斷變化,甚至變化的類型也無法預測。例如幾年前沒人知道 Kubernetes 是什麼,現在它已有全球數千名開發者參與的多場研討會
  • 新能力的出現:架構可能不只是用新工具取代舊工具,而是整個轉向新典範。例如 Docker 容器化帶來的巨大影響,以及它對架構師、工具和工程實踐的衝擊
  • 變化的加速:生態系統不只是持續變化,變化的速率也在不斷上升
  • Domain 的變化:開發者撰寫軟體所服務的領域持續演變
  • 技術變遷:組織會嘗試跟上至少部分技術變化
  • 外部因素:許多僅與軟體開發間接相關的外部因素也會驅動變化,例如授權成本的變化

無論組織在架構時尚中處於什麼位置,架構師都應該了解當前的產業趨勢,以便在何時跟隨、何時例外做出明智的決策。

決策準則(Decision Criteria)#

選擇架構風格時,架構師必須考慮影響 domain design 結構的各種因素。基本上,架構師設計兩件事:指定的 domain,以及使系統成功所需的所有其他結構元素。

架構師應在做設計決策時掌握以下資訊:

The Domain(領域)#

  • 理解 domain 的重要面向,特別是影響 operational architecture characteristics 的部分
  • 不必成為領域專家,但必須對主要面向有良好的整體理解

Architecture Characteristics that Impact Structure#

  • 發現並闡明支撐 domain 和其他外部因素所需的架構特性

Data Architecture(資料架構)#

  • 架構師必須與 DBA 合作處理資料庫、schema 和其他資料相關考量
  • 必須理解資料設計對架構的影響,特別是新系統需要與舊有資料架構互動的情況

Organizational Factors(組織因素)#

  • 外部因素可能影響設計,例如特定雲端供應商的成本
  • 公司可能計畫進行合併與收購,促使架構師傾向開放解決方案和整合架構

Knowledge of Process, Teams, and Operational Concerns#

  • 軟體開發流程、與 operations 的互動、QA 流程等都會影響設計
  • 例如組織在 Agile 工程實踐方面缺乏成熟度,那些依賴這些實踐的架構風格就會遇到困難

Domain/Architecture Isomorphism#

  • 某些問題領域天然匹配特定架構的拓撲結構
  • 例如:需要高度客製化的系統適合 microkernel;需要大量離散運算的基因組分析適合 space-based architecture
  • 反之亦然:高度可擴展的系統不適合大型 monolithic 設計;高度語義耦合的問題領域不適合高度解耦的 distributed architecture

Monolith vs Distributed#

架構師必須做出幾個關鍵判斷:

單一或多組架構特性?#

  • 使用 quantum 概念,判斷單一組架構特性是否足夠,還是系統不同部分需要不同的架構特性
  • 單一組 → 暗示 monolith 即可(但其他因素仍可能導向分散式)
  • 不同組 → 暗示需要 distributed architecture

資料應該在哪裡?#

  • Monolithic → 通常假設單一或少數關聯式資料庫
  • Distributed → 必須決定哪些服務持久化資料,以及資料如何在架構中流動
  • 架構師必須同時考慮結構和行為,不要害怕透過迭代找到更好的組合

通訊風格?#

  • 確定資料分區後,下一步是決定同步或非同步通訊
  • Synchronous 在大多數情況下更方便,但可能導致 scalability、reliability 等問題
  • Asynchronous 在效能和擴展性方面有獨特優勢,但帶來資料同步、deadlock、race condition、debugging 等挑戰

預設使用 synchronous,在必要時才使用 asynchronous。

從哪裡開始?Domain Partitioning vs Technical Partitioning#

設計流程的輸出是 architecture topology(架構拓撲),需考慮:

  • 選擇什麼架構風格(以及混合方案)
  • 架構決策記錄(Architecture Decision Records),記錄設計中最需要架構師投入的部分
  • 架構適應度函數(Architecture Fitness Functions),保護重要原則和運營架構特性

案例研究#

Monolith 案例:Silicon Sandwiches#

經過架構特性分析,確定單一 quantum 即可。加上預算有限,monolith 的簡潔性很有吸引力。兩種設計方案:

  • Modular Monolith:以 domain 為中心的組件搭配單一資料庫,部署為單一 quantum。如果時間和資源允許,應將資料庫資產也按 domain component 分離,以便未來遷移到分散式架構
  • Microkernel:利用 domain/architecture isomorphism——Silicon Sandwiches 的客製化需求天然匹配 microkernel 的 plug-in 結構。核心系統包含 domain components 和單一關聯式資料庫,每個客製化以 plug-in 形式出現,並利用 Backends for Frontends (BFF) 模式讓 API layer 成為輕量的 microkernel adaptor

Distributed 案例:Going, Going, Gone (GGG)#

此系統需要不同部分有不同的架構特性(如 auctioneer 與 bidder 的 availability 和 scalability 不同),且需要高度的 scale、elasticity、performance 和細粒度的客製化。

  • 候選方案:low-level event-driven 或 microservices
  • Microservices 更好地支持不同部分的不同 operational architecture characteristics
  • Performance 是挑戰,但架構師可以透過設計來彌補——例如減少過度 orchestration、避免過度激進的資料分離

Figure 18.3: A microservices implementation of Going, Going, Gone

Figure 18.4: The quanta boundaries for GGG

選擇架構風格不存在「正確答案」。架構師的工作是理解 trade-offs,在眾多約束條件下找到最適合的方案,並透過迭代不斷改進設計。