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
- Simon Brown: C4 Model
- 對於架構本身的描述,沒有紀錄標準
- ADR即架構文件
ADR的段落
標題
- 架構決策的簡短描述
- 加上可簡易識別的識別碼,例如順序的編號
- 例如在
ADR42. 在訂購服務與付款服務之間使用非同步通信
狀態
- 三個狀態:提議、接受、取代
- 提議:還需要更高的決策者,或委員會的同意
- 接受:Decision is made
- 取代:這個決策已經被另一個ADR取代
- 不會有還在提議狀態中的ADR被取代
- 提議中的ADR要修改就直接修改在該ADR中
- 例如:
ADR42. 在訂購服務與付款服務之間使用非同步通信
狀態:取代。被ADR68取代
ADR68. 在訂購服務與付款服務之間使用同步REST API
狀態:接受。取代ADR42
- 狀態段落有個重要的目的:強迫架構師與老闆進行必要的會議 - 才有辦法寫出ADR的狀態
- 讓對話有好的開始的三個重要議題:
- 費用
- 跨團隊的影響
- 安全性
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人在此受傷