「請介紹一下系統架構。」每次開始新一輪面試時,這個問題總會讓我措手不及,因為超過三成的公司會突然丟出這樣的問題,沒有上下文也沒有任何前提。
經歷幾次後,我開始習慣詢問我認識的軟體工程師,不論是資深的、資淺的,還是前端後端的同事,甚至是主管。令我驚訝的是,得到的答案各不相同…某方面來說也算是挺有趣的,因此我決定開始這個系列,認真介紹系統架構這個大概念及其相關內容。
一般來說,系統架構可以從三個角度來理解:業務層面、軟體層面和硬體層面。這些角度讓我們能夠全面切入所提供的服務內容。由於本篇文章主要聚焦於軟體層面的系統架構,因此對於其他兩個層面的討論將不作深入,可以參考這位大大的文章《我的專案筆記 #24》搞懂系統架構,讓你知道工程師在說什麼!! - 不用會寫程式碼,也可和工程師溝通。
在軟體層面的系統架構中,主要有三個部分需要討論:架構模式、技術選型和性能優化。接下來,我們將逐一介紹這些部分。
以下介紹一些比較常見的架構模式以及優缺點:
一體化架構,又稱為「單體架構」,其主要特點是所有功能和內容都在一個應用中實現,因此程式碼之間的耦合度較高,這會導致擴展性差和維護困難。
過去的專案普遍採用這種模式,因此當你接手這類專案時,常常會感受到「人生好難」、「有夠難調整」的挫折。目前此架構仍然常用於較小型的應用或是外包產業。
微服務架構旨在降低程式碼和服務之間的耦合,以解決一體化架構下的高耦合問題。這種架構將每種服務從單一應用中解耦,轉變為獨立且小型的服務,並通過API交換資料。[註1]
這種方式允許每個服務獨立進行更新、開發、部署和擴展,雖然提升了靈活性,但也增加了系統的複雜度。此外,由於其特性十分適合敏捷開發方法,近年來許多台灣企業逐漸轉型為微服務架構。
事件驅動架構是一種現代的架構模式,概念上結合了微服務架構與序列處理。其主要特點是透過一個事件觸發下一個事件,並且事件之間保持鬆耦合的狀態。
與微服務架構相似,由於具備低耦合性,事件驅動架構具有很高的擴展性。此外,事件觸發的方式使其特別適合處理高併發的情況。然而,在追蹤事件流時可能會面臨困難,因此在這方面需要特別設計以確保資訊內容的有效傳遞。
服務導向架構的核心是前面提到的業務架構,旨在以業務功能為導向來設計軟體服務。因此,每個服務都可以被視為一個獨立的功能單位。由於直接聚焦於業務服務本身,這種架構提高了重複使用性,使其特別受到大型企業的青睞。
分層架構,可以被視為 MVC 架構的擴展版本,它將應用劃分為多個層次以實現職責的明確分工,從而避免互相干擾,並使維護和擴展更加容易。然而這種架構的缺點也相當明顯——由於每個事件都需經過多個層,對於不需要複雜處理的事件(例如簡單的資料庫 CRUD 操作),多層設計可能會導致效能下降。
無服務架構是一種新興的架構模式,它利用雲服務(例如 AWS、GCP)取代傳統的實體硬體設備來運行程式碼。這種架構的最明顯優點是成本下降。與過去購置和維護硬體設備的高成本相比,使用雲服務只需根據實際使用量支付費用,這樣的付費模式更具靈活性。
在確定架構模式後,下一步便是技術選型。根據所選擇的架構,我們需要決定技術層面上要使用的內容,通常包括以下幾個方面:
另外,值得注意的是,選擇的程式語言和框架是否活躍維護也相當重要,畢竟使用一個未被維護的程式語言是非常危險的!
一個項目在持續運行多年後,不論最初使用了什麼系統架構或技術選型,總會出現一些問題,例如框架的效能瓶頸或架構的擴展性不足。在這種情況下,除了對程式碼進行重構,還可以考慮調整最初的系統架構來解決問題,可能會有以下幾種情境:
由於所有功能集中在一個應用中,針對各個功能的優化和擴展會較為困難。因此,可以考慮改為微服務架構,專門針對不同服務進行性能優化,甚至允許高流量的服務進行動態擴展,或使用不同的數據庫技術來加快操作速度。
在分層架構中,數據層的設計直接影響查詢效率和數據存取性能,因此選擇合適的資料庫和設計可以顯著提高性能。在事件驅動架構中,可以通過非同步處理來減少延遲,優化用戶體驗。事件流的處理效率直接影響整個系統的性能。
服務導向架構和微服務架構允許系統根據需求進行擴展,進而提高性能。例如,可以針對某些特定服務進行水平擴展,以應對高流量。而無服務架構則透過雲平台的自動擴展功能,根據實際使用情況動態調整資源配置,從而優化性能。
我想引用一位軟體工程師朋友對這種面試題目的感想:「不知道在面試時問這種問題,是不是因為主管沒什麼料,才不知道該問什麼?」雖然這句話聽起來有些犀利,但我很喜歡(?)。
畢竟,這個問題實在太大了,難以用三言兩語回答。就像有人突然問你:「股票是什麼?」這個問題的範疇從賺錢的工具到公司的分權,答案可以涵蓋的面向太多了。而且,有時面試官其實只是想聽到某一特定系統架構的介紹而已[註2],所以現在在面試時遇到這類問題,我通常會先詢問對方想知道哪種架構。
說不定,對方真的只是苦於不知道該選擇哪種系統架構,隨意問問而已呢。
[註1] 此處所提到的服務獨立,並不僅限於使用者介面上的明顯區隔,而是包含程式碼層面的真正分離。
[註2] 我曾經有一次的面試經驗是,當我介紹微服務架構時到一半時突然被面試官打斷,並被告知:「看來你不懂系統架構,不用回答了。」