Skip to main content

Ch19: 架構決策

反模式

  • 這是不對的事,但大家還是一直做
  • 以下三種反模式,通常漸進式的依序出現

1. 掩蓋資產反模式

Covering Your Assets Anti-Pattern

  • 架構師因為害怕出錯而逃避,或遲不作出決定
  • 後果
    • 使得開發團隊無從開始工作,而耽誤進度
  • 克服方法
    • 等到不得不下決定能下決定的最後的時間點才作出重要決定 (Wait unil the last responsible moment)
    • 與開發團隊緊密合作,確保決策能被預期地實現
Discussion

架構決定:推遲到能下決定的最後時間點才下決定

技術決定:盡可能地推遲技術細節的決定時間點

為何不能早點做決定?早決定有什麼不好?

2. 土撥鼠日反模式

  • 人們不知為何做決策,無法提供一個完整的「理由」時
  • 後果
    • 人們不斷地再度討論
  • 克服方法
    • 證明架構決定能提供商業價值
    • 費用、上市時間、使用者滿意度、策略定位

3. 電子郵件驅動架構反模式

  • 人們遺失、忘記,或甚至不知道架構決策已經制定
  • 後果
    • 導致架構決策無法實現
  • 克服方法
    • 「Hi Sandra,我做了一個會直接影響你與服務之間通信的重要決定。請用底下的連結檢視該項決定...」
    • 講背景,但不提決定本身
    • 嚇嚇他,讓他覺得這是重要的事:「會直接影響你」
    • 使用單一的紀錄系統:「使用連結檢視...」

真正重要的是什麼?

  • 只要會影響架構的決定,那它就也是重要的

結構

  • 採用的風格或模式的決策
  • 例如
    • 在微服務的架構中,讓組件(Component)之間分享資料的決定,會影響組件的Bounded Context
    • 在分層風格的架構中,跨層存取資料的決定

非功能特性

  • 指架構特性 (即:非功能性需求。作者不喜歡稱其為「需求」所以改叫它「架構特性」)
  • 例如
    • 某個會影響效能的技術,而效能又是這個系統需要重點考慮的面向。那這個技術決定就會是重要的架構決定

相依性

  • 系統中元件與服務之間的耦合點。會影響整體的可擴展性、模組性、敏捷性、可測試性、可靠性

介面

  • 系統元件如何被存取,與協作的方式
  • 決定了很難脫離的了
  • 例如
    • API Proxy, Service Bus, Framework

建造技巧

  • 有關平台,框架,工具,使用的技術
  • 例如
    • 要不要外包,買現成的,上雲...etc.

架構決策紀錄ADR

ADR: Architecture Decision Records

Why ADR?

  • 圖示架構的標準有很多種
    • Simon Brown: C4 Model
      • Top-down的四個階層各有一張圖
      • Context, Container, Component, Code
    • Open Group ArchiMate
      • 3 Layers: Business, Application, Technology
      • Type of releations: Structural, Dynamic, Other
      • Cross-layer depdendency
  • 對於架構本身的描述,沒有紀錄標準
  • ADR即架構文件

ADR的段落

標題

  • 架構決策的簡短描述
  • 加上可簡易識別的識別碼,例如順序的編號
  • 例如在ADR42. 在訂購服務與付款服務之間使用非同步通信

狀態

  • 三個狀態:提議、接受、取代
    • 提議:還需要更高的決策者,或委員會的同意
    • 接受:Decision is made
    • 取代:這個決策已經被另一個ADR取代
      • 不會有還在提議狀態中的ADR被取代
      • 提議中的ADR要修改就直接修改在該ADR中
  • 例如:
    • ADR42. 在訂購服務與付款服務之間使用非同步通信

      狀態:取代。被ADR68取代

    • ADR68. 在訂購服務與付款服務之間使用同步REST API

      狀態:接受。取代ADR42

  • 狀態段落有個重要的目的:強迫架構師與老闆進行必要的會議 - 才有辦法寫出ADR的狀態
  • 讓對話有好的開始的三個重要議題:
    1. 費用
    2. 跨團隊的影響
    3. 安全性
Question

為什麼跟老闆/主管開會,談這三件事會讓對話有好的開始?

背景

  • 促成此決策的原因為何?
  • 寫下「什麼情況讓我做出這樣的決定」,可能的話,簡單的說明其他替代方案

決策

  • 最後關於此ADR的決策及理由
  • 語氣:要用很肯定、威嚴的語氣。而且不要採被動式
    • 💚 「我們會使用非同步方式傳輸,因為...」
    • 💔 「我認為服務間採取非同步傳輸是最佳選擇,因為...」
  • 這是整個ADR最具威力的段落,讓架構師強調「為何」而非「如何」
  • 協助人們清楚問題的背景,避免犯下重構至另一個可能產生問題的方案

後果

  • 決策的後果影響為何?
  • 每個決策都有其影響,不論好壞
  • 詳細說明這個架構決策會帶來的影響
    • 用來記錄架構決策的取捨分析
  • 例如:
    • 「使用非同步傳輸,能夠大幅增加貼文審查的回應性,從3100ms降到25ms」
    • 「使用者要得知其貼文的審查情形,需要實作額外的Websocket通道才能推送結果」

合規

  • 如何確保此項決策被符合?
  • 強迫架構師在下決定時,同時也思考這個決定該怎麼被測量、管理,進一步到落實
  • 例如
    • 架構決策:「採用分層式架構設計,所有組建不得跨層通訊」
    • 可以用自動化工具檢查是否合規 (e.g. Java ArchUnit; C# NetArchTest)

註解

  • 這項決策的後設資料,例如作者等

ADR的範例

ADR 76. 出價服務之間的非同步發布/ 訂閱傳訊


  • 狀態

    接受
  • 背景

    出價記錄服務,收到來自於線上出價人或透過拍賣人的現場出價後,必須將其轉送至出價串流及出價追蹤服務。這可以透過線上拍寶 API 層,利用非同步的點對點(p2p)傳訊、非同步的發布/ 訂閱傳訊、或 REST 來實現。
  • 決策

    我們會在出價記錄服務、出價串流服務、及出價追蹤服務之間,使用非同步發布/訂閱傳訊。 出價記錄服務不需要從出價串流服務、或出價追蹤服務回傳資訊。 出價串流服務所收到出價的順序,必須與這些出價被出價記錄服務收到的順序完全一致。使用傳訊及佇列能夠自動保證串流裡的出價順序。 使用非同步發布/訂閱傳訊可提高出價程序的效能,讓出價資訊的擴充性得以實現。
  • 後果

    我們需要叢集以及訊息佇列的高可用性。 內部出價事件會跳過 API 層執行的安全檢查。 更新:根據 04/14/2020 的 ARB 會議審查,ARB 決定接受這項取捨,市且這些服務之間的出價事件不需要額外的安全檢查。
  • 合規

    我們利用週期性人工的程式碼及設計審查,來確保出價記錄服務、出價串流服務、及出價追蹤服務之間,使用的是非同步發布/ 訂閱傳訊。
  • 註解

    作者:Subashini Nadella
    同意人:ARB 會議成員,04/14/2020
    最後更新:04/15/2020, Subashini Nadella

以ADR作為標準

  • 標準(Standard)的存在就只是為了控制人們做事的方法

    • 很少人會喜歡
    • 因為很難帶來幫助
    • e.g. 訂定「超速我就罰你錢」的標準,來改善超速問題
  • ADR作為標準可以改善這種作法

    • 不只指示標準為何,更解釋為何標準需要存在
    • 說明了不遵守標準的後果
    • 持續檢視標準是否有改善空間
    • e.g. 「超速我就罰你錢」,因為這裡常有人超速,一年有ooo人在此受傷