Ch9: Foundations#

本章介紹架構風格的基礎知識,包含基本模式(fundamental patterns)以及 monolithic 與 distributed 架構的分類方式。


Fundamental Patterns(基本模式)#

幾個基本模式在軟體架構的歷史中反覆出現,架構師應先熟悉這些模式,再深入學習現代架構風格。

Big Ball of Mud#

  • Big Ball of Mud 是指缺乏任何可辨識架構結構的系統,也是一種反模式(anti-pattern)
  • 特徵:結構雜亂、spaghetti code、資訊在系統各處被全域共享或複製
  • 缺乏結構使得變更極為困難,且在 deployment、testability、scalability 和 performance 上都會出現問題
  • 雖然沒有架構師刻意設計這種架構,但實務中因缺乏治理(governance)而意外產生的情況非常常見

Figure 9.1: A Big Ball of Mud architecture visualized from a real code base

Unitary Architecture#

  • 最早期的軟體架構形式——軟體與硬體是單一實體
  • 現代幾乎只存在於嵌入式系統或高度受限的環境中
  • 隨著系統功能成長,通常需要 separation of concerns 來維持 performance 和 scalability

Client/Server#

將前端與後端的技術功能分離,是許多架構風格的基礎。常見變體:

  • Desktop + Database Server — 早期 PC 時代的架構,桌面應用程式連接獨立的資料庫伺服器
  • Browser + Web Server — 現代 Web 開發的典型分離方式,瀏覽器作為 thin client
  • Three-Tier — 在 1990 年代後期流行,包含 database tier、application tier、frontend tier

Java 語言設計時正值 three-tier 架構盛行,因此將 serialization 機制內建於語言核心。然而該架構風格已式微,serialization 的遺留卻仍困擾著 Java 至今。這提醒我們:將架構假設嵌入語言設計中可能帶來長期的負面影響。


Monolithic vs. Distributed Architectures#

架構風格可分為兩大類型:

  • Monolithic(單體式)— 單一部署單元,包含所有程式碼
  • Distributed(分散式)— 多個部署單元,透過遠端存取協定連接

Monolithic 架構風格:

  • Layered architecture(Ch10)
  • Pipeline architecture(Ch11)
  • Microkernel architecture(Ch12)

Distributed 架構風格:

  • Service-based architecture(Ch13)
  • Event-driven architecture(Ch14)
  • Space-based architecture(Ch15)
  • Service-oriented architecture(Ch16)
  • Microservices architecture(Ch17)

分散式架構在 performance、scalability、availability 上更強大,但代價是必須面對一系列 monolithic 架構不會遇到的挑戰。


Fallacies of Distributed Computing(分散式運算的八大謬誤)#

由 L. Peter Deutsch 等人在 1994 年於 Sun Microsystems 提出,這八個謬誤至今仍適用於所有分散式架構。

Fallacy #1: The Network Is Reliable#

  • 網路並不可靠,服務之間的通訊隨時可能失敗
  • 因此需要 timeout 和 circuit breaker 等機制
  • 系統越依賴網路(如 microservices),可靠性就越低

Figure 9.2: The network is not reliable

Fallacy #2: Latency Is Zero#

  • 本地方法呼叫以 nanosecond/microsecond 計算,遠端呼叫以 millisecond 計算
  • 架構師必須知道生產環境的平均延遲和 95th/99th percentile 延遲
  • 連鎖呼叫的延遲會累積:10 個 service call 各 100ms = 請求增加 1,000ms

Figure 9.3: Latency is not zero

Fallacy #3: Bandwidth Is Infinite#

  • 分散式架構中,服務間的通訊會大量消耗頻寬
  • Stamp coupling 是常見問題:服務回傳大量不必要的資料(例如回傳 500kb 但只需要 200 bytes)
  • 解決方式:私有 RESTful API、field selector、GraphQL、consumer-driven contracts(CDCs)、內部 messaging endpoint

Figure 9.4: Bandwidth is not infinite

Fallacy #4: The Network Is Secure#

  • 分散式架構的每個 endpoint 都必須被保護
  • 從 monolithic 轉為 distributed 後,攻擊面大幅增加
  • 安全性檢查也是 synchronous distributed architecture 效能較低的原因之一

Figure 9.5: The network is not secure

Fallacy #5: The Topology Never Changes#

  • 網路拓撲(routers、switches、firewalls 等)持續在變化
  • 一次「小型」網路升級就可能讓所有延遲假設失效,觸發 timeout 和 circuit breaker
  • 架構師必須與網路管理員保持密切溝通

Figure 9.6: The network topology always changes

Fallacy #6: There Is Only One Administrator#

  • 大型企業有數十位網路管理員,架構師需要與多方協調
  • 這反映了分散式架構的協作複雜度遠高於 monolithic

Figure 9.7: There are many network administrators, not just one

Fallacy #7: Transport Cost Is Zero#

  • 這裡的「成本」不是指延遲,而是指實際的金錢成本
  • 分散式架構需要額外的 hardware、servers、gateways、firewalls、proxies 等基礎設施
  • 分散式架構的總成本通常顯著高於 monolithic

Fallacy #8: The Network Is Homogeneous#

  • 大多數企業的網路由多家硬體供應商組成
  • 不同供應商的硬體互操作性並非完美,可能導致封包遺失
  • 這個謬誤會連帶影響前面所有的謬誤

Figure 9.9: The network is not homogeneous


Other Distributed Considerations#

除了八大謬誤外,分散式架構還面臨以下挑戰:

  • Distributed logging — 日誌分散在數十到數百個不同位置,root-cause analysis 極為困難
  • Distributed transactions — 無法使用傳統 ACID 交易,需依賴 eventual consistency。常見方案包含 transactional sagas(使用 event sourcing 或 finite state machine)和 BASE transactions(Basic Availability, Soft state, Eventual consistency)
  • Contract maintenance and versioning — 服務間的合約(contract)建立、維護與版本管理是一大挑戰,尤其是跨團隊的 decoupled services

分散式架構帶來強大的 scalability 和 availability,但代價是犧牲資料一致性(data consistency)與資料完整性(data integrity)。在選擇分散式架構前,務必充分評估這些 trade-offs。