廣告
如何建構系統架構?從單點到維度的軟體設計思考模型 - 好的架構不只是畫圖!探討如何從功能、性能、安全性與可擴充性等多個維度評估系統設計,培養開發者在權衡 (Trade-off) 間做出最佳決策的核心能力。

如何建構系統架構?從單點到維度的軟體設計思考模型

Last updated on

在研究某個軟體的系統架構,發現一個值得探討的問題。

當設計系統架構時,使用何種的視界去分析與設計,會得到不一樣的設計結果,但結果是否為當下最佳的解決方案?

局部視角

假設後端服務的開發團隊,收到開發 APIs 的任務,而且此 APIs 需公開於開放網路。

開發團隊以專業角度出發,基於資安考量的前提下,規劃每一支 API 的請求,都會進行 API 存取合法性的驗證。所以建立 Identity Server,負責 Token 的發送與驗送。

  • 在每次呼叫 API 之前,都必須先取得一組 Token 資訊,這組 Token 資訊會包含著請求的有效時間限制以及使用者的資訊。
  • 在呼叫 API 時,將取回的 Token 作為必要參數,一同送至 API。
  • API 收到請求後,先進行 Token 的驗證。驗證失敗,直接中斷動作,反之,成功回傳 API 的資訊。
design base on API
design base on API

這種做法是很合理,因為 APIs 的本身暴露在公開的網路環境中,基於零信任的原則,所以必須對每組 API 的請求,都進行相關身份的驗證。

若思考的維度只關注在 APIs 的本身,很容易會陷入一種情境。當系統發現異常或整合問題時,APIs 端的開發人員會堅持 APIs 的設計沒有問題,一定是其他部份有問題,或是使用端有問題。

當前端與後端分別不同部門,在穀倉效率的影響下,這種事其實蠻容易發生的。因為大家都會站在自己的專業角度去進行設計,個別負責部份都很完美,但組合起來的時候就會發現一些很奇妙的問題。

全局視角

當思考的維度,從單純的 APIs 開發角度抽離,改為關注 APIs 所服務的對象、系統架構的全貌,客戶所關心的重點。

與相關人員確認後,會發現 APIs 主要提供站台使用,可以初步勾勒出的系統的全貌。

站台呼叫 API
站台呼叫 API

與站台的開發人員,確認會從 JavaScript 直接呼叫 APIs,進行業務層級的操作。

純前端呼叫 API
純前端呼叫 API

再進一步確認使用情境,發現首頁與特定頁面,需要使用 server side rendering(SSR) 產出頁面。以首頁為例,產出頁面過程中,需要呼叫 10 支 API 組成所需資料。

站台呼叫 API
站台呼叫 API

試著從分析 Client 站連入首頁時,系統一連串的動作行為,會發現在載入 server side rendering 的頁面時,所需要觸發的 API 背後的動作。

  1. 首先跟 Identity Server 取得一組 Token。
  2. 利用 Token,進行 API 的呼叫。
  3. APIs 收到請求後,會將 Token 傳到 Identity Server 進行驗證。
  4. 驗證成功後,進行 API 本身的職責,並回傳結果。

發現步驟 2~4 重覆 10 次,每個 API request 都會呼叫一次 Identity Server,進行 Token 的驗證。

總觀來看,其中 9 次的 Token 驗證其實是一個重複性的動作。當然不能說這一個設計有問題,可是從全面性的角度去審視系統架構整體,發現這樣的設計,會對 Identity Server 造成額外的負載,就需要評估這些負載的損耗是必要的嗎?或是可以節省下來?

當從局部的角度,去看待一件事情的時候,只有那一個範圍。當評估的維度,往上再拉一層,從全局的角度去看待這件事情的時候,其實會發現當初的最佳解,或許對整個系統而言可能是一個脆弱環節或是瓶頸。

實際的解法方向

既然發現了 10 次重複驗證 Token 的問題,從全局視角出發,我們可以怎麼解?

常見的做法是引入 API Gateway 來統一處理外部請求的授權驗證,讓後端的 microservices 信任 Gateway 轉發的請求;或是導入 BFF (Backend for Frontend) 設計模式,由一個專屬的 Backend 伺服器去跟後端要資料並聚合成一包,讓前端只需打一次 API 即可。

這類架構的補強,正是我們從「單一 API 視角」切換到「全局視角」後才能看見的權衡價值。

(註:想知道缺乏全局視角會造成什麼嚴重的系統慘劇嗎?可以看我的這篇除錯實戰紀實:API 流量異常暴增?抽絲剝繭找出現代軟體架構的隱形殺手)

小結

回歸到問題的本質,就是設計之初,是否有看見全貌,明白了解這個系統主要要解決的痛點是什麼?客戶要的是什麼?

其實在大多數的情況下,客戶根本不在意是用什麼樣的技術和方法,能不能解決問題、是否能滿足業務上的需求,這才是他們關注的重點。

局部最佳解,有時並非系統的最優解。

從局部最佳解來看的話,有時需要額外投入更多的資源進行開發。一旦回到全局的角度來看,有些設計其實是多餘的,或是對系統造成額外負擔。

一但發生未滿足客戶的要求,後續可能需要二次調整,這是一種過度設計造成的成本浪費。

倒不如在專案之初,所有成員提出方法後,進行系統全面性的審視,有時候就可以發現某些功能和設計其實是可以被忽略,或是發現有部分情境未被考慮,在未來可能是系統脆弱的環節。

延伸閱讀


💡 互動時間 軟體開發最難的往往不是寫 Code,而是避免陷入「穀倉效應」的局部優化。 你在團隊開發中,也曾遇過各部門堅持「局部最佳解」,反而導致系統整體效能崩盤的災難案例嗎?歡迎在下方留言,一起探討架構設計的取捨之道!

💬 留下你的想法

有問題、不同看法,或是你踩過類似的坑?歡迎留言討論,我會盡量回覆。