第四種耦合是基礎建設耦合(infrastructure coupling),與執行期耦合一樣影響執行期行為。

應用元件運行於、並消耗各種基礎建設——包括基本的 compute 與網路資源,以及資料庫、訊息中介者等服務。

共用同一基礎建設的元件,即為基礎建設耦合;即使彼此不直接或間接通訊,也會透過資源競爭或配置變動互相影響

基礎建設耦合的範例#

延續 Customer Service 與 Order Service 的例子:

  • Customer Service 一方面支援 Order Service 管理可用信用額度,另一方面還要管顧客帳號等其他職責。
  • 簡單部署方式:兩個服務跑在同一個 Kubernetes 叢集、共用同一台資料庫伺服器
  • 表面上沒問題,但因為共用基礎設施,實際上會互相干擾——較不關鍵的 Customer Service 可能拖垮關鍵的 Order Service

Figure 4.16: Multiple services sharing infrastructure can degrade each other's runtime behavior

兩種基礎建設耦合#

競爭資源(Competition for Resources)#

  • Kubernetes 可以為容器設定 CPU 與記憶體上限。只要記得設,Customer Service 就無法把 Order Service 的 CPU/記憶體吃光。
  • 但其他資源仍可能被搶佔:
    • 網路頻寬:Kubernetes 不一定能限制。
    • 資料庫連線、鎖:Customer Service 可能耗盡資料庫連線、用昂貴查詢拖慢 server,或長時間握有鎖,讓 Order Service 阻塞。

配置變更帶來的非預期後果#

  • 複雜系統失敗的常見原因之一,就是配置變更引起意料之外的副作用。
  • 例如:為了 Customer Service 修改 Kubernetes 叢集或資料庫的某項設定,可能無意間影響到 Order Service。

最小化基礎建設耦合的策略#

對「真正關鍵」的服務,結合「服務設計」與「部署策略」兩面下手:

  • 執行期解耦:把關鍵服務設計為不會因其他服務故障而失敗(見上一節的策略,例如把責任搬移、改用非同步訊息)。
  • 獨立基礎建設:把關鍵服務部署在自己的基礎設施上,搭配獨立的基礎服務(資料庫、message broker 等)。

範例:讓 Order Service 高可用——

  • 將「可用信用額度」併入 Order Service,使 POST /orders 在 Order Service 內本地完成。
  • 把 Order Service 部署到獨立的 Kubernetes 叢集,並使用獨立的資料庫伺服器
  • 結果:createOrder() 完全由 Order Service 與其專屬基礎設施處理;沒有跨服務的資源競爭,也不會被其他服務的配置變更影響。

Figure 4.17: To minimize infrastructure coupling, critical services should be deployed on separate infrastructure

不必把所有服務都這樣做——獨立基礎設施有成本。把資源花在真正關鍵、必須高可用的服務,讓其他服務共用普通基礎建設,通常是合理的取捨。

章節重點摘要#

  • 兩個軟體元素耦合,當一個能影響另一個(無論在開發期或執行期)。
  • 四種耦合:設計期、建置期、執行期、基礎建設。
  • 鬆設計期耦合:讓變更局部化,提升團隊自主性與修改便利性,流暢交付的核心。
  • 鬆建置期耦合:減少需重新編譯與測試的子專案,加速部署管線,大型程式碼庫尤其重要。
  • 鬆執行期耦合:降低一個元件失敗或變慢拖累另一個元件的機率,維持高可用與低延遲。
  • 鬆基礎建設耦合:避免因資源競爭或配置變更讓元件之間互相影響,維持高可用。
  • 雖然鬆耦合普遍是好事,但有些耦合不可避免,把它消除可能反而帶來顯著代價;用內聚把不可避免的緊耦合管理在合適的層級才是務實做法。