對於“軟體架構”這個詞有很多定義和含義。而且,“軟體開發”、“軟體設計”和“軟體架構”這三個概念之間存在相當大的重疊,它們在許多方面相互交融。 從核心上看,可以將軟體架構視為在構建應用程式時,對不同選擇進行權衡的學科。 1 為什麼需要權衡以及我們為什麼在意? 我們在構建軟體時必須進行權衡的原因,與其 ...
對於“軟體架構”這個詞有很多定義和含義。而且,“軟體開發”、“軟體設計”和“軟體架構”這三個概念之間存在相當大的重疊,它們在許多方面相互交融。
從核心上看,可以將軟體架構視為在構建應用程式時,對不同選擇進行權衡的學科。
1 為什麼需要權衡以及我們為什麼在意?
我們在構建軟體時必須進行權衡的原因,與其他學科中的權衡原因相同。計算系統是複雜的,複雜性越高,實現特定系統的全部目標的方式就越微妙。這些目標:
- 既可以是功能性的(例如提供用戶自助服務的能力、處理特定事件、接受某些輸入並產生輸出)
- 也可以是非功能性的(例如每秒處理數百萬個請求、實現零信任安全、提供100毫秒以下的響應時間)
如金融投資中,人們普遍理解風險與收益之間的權衡。投資越風險,潛在的財務回報越大。投資越安全,預期收益就越小。
同樣的規則也適用於計算,特別是在設計分散式應用程式時。許多組織遇到的問題不是他們必須做出某些讓步或權衡,而是大多數組織要麼對自己所做的權衡不瞭解,要麼缺乏系統的、明確的和有效的方法來進行這些權衡。
本“架構權衡”系列的目的是闡明在軟體架構的不同原則之間進行權衡時的決策過程以及此類決策的具體技術影響。
2 我們在權衡什麼?
如上所述,大多數與系統和應用程式架構相關的決策都涉及某種程度的權衡。
既然我們已經知道為什麼需要討論、權衡和有意識地思考架構權衡,我們可以談談我們實際在系統和應用程式中進行權衡的方面。
這些架構權衡有時分為兩大類:
- 系統的基本架構特性有關(如可擴展性與簡潔性)
- 與具體技術、機制和架構風格有關(如同步通信與非同步通信、Kafka與消息匯流排等)。前者更為廣泛的權衡類別也決定了更具體的權衡
本文重點討論第一類架構權衡——基礎架構特性。
因此,當我們談論架構權衡時,我們實際上是在討論我們希望支持哪些架構特性並將其納入我們的主要目標。另一方面,我們也在識別那些我們有意識地決定不太關註或完全放棄的架構特性,以便更加重視那些我們認為更重要的特性。
下麵是一些架構特性和一些常見的權衡場景。
3 架構特性
當談論系統或應用程式架構的固有或基礎特性時,我們實際上是指一組關鍵屬性,這些屬性定義了特定的系統或應用程式。以下是這些特性的一小部分示例。這絕不是一個詳盡的列表,還有許多其他的架構特性。
- 可擴展性
- 可觀測性
- 可審計性
- 彈性
- 響應性
- 可測試性
- 互操作性
- 可維護性
- 可支持性
這些特性有時被稱為“系統屬性”、“架構屬性”或乾脆稱為“尾碼-ility”屬性。
這些系統特性或屬性乍看之下似乎是獨立的,但實際上,它們中的許多是相互交織的,可能有直接或反向關係。
4 互操作性 vs 可擴展性、彈性和響應性
讓我們以互操作性為例。為了使系統具備互操作性,它需要能夠輕鬆地與其他系統進行交互和通信。這通常意味著所有這些系統都需要使用通用協議。它們需要使用共同商定的標準,並且這些標準還需要設計得易於將來的系統也能相對輕鬆地“插入”到這種通信中。
然而,如果一個系統優先考慮互操作性,這很可能會影響系統的可擴展性。
舉個具體的例子,假設現有的應用程式使用REST協議(依賴HTTP)進行通信。假設我們要引入一個新系統。為了使這個新應用程式與現有的應用程式互操作,我們決定該應用程式的所有進出通信都通過REST/HTTP進行。這看起來很合理。
然而,如果將新系統的通信限制在依賴HTTP上,可能會限制其響應能力和可擴展性,尤其是在需要處理大量請求的情況下。假設這個新系統需要每秒處理數百萬個請求,並且是非同步的(即調用者無需等待應用程式確認其已處理請求)。這種情況下,由於需要非同步通信且Kafka協議(理論上)比HTTP開銷更小,這種場景可能更適合使用事件驅動技術如Kafka。
換句話說,在這種情況下,互操作性與響應性以及可擴展性呈反比關係。
5 簡單性、易上手性和可支持性 vs 響應性
另一個可能不太技術性、更具組織性的權衡發生在決定以易於支持作為主要架構驅動因素時。這可能意味著使用技術團隊熟悉的技術。這也可能意味著使用行業內廣泛使用和已知的技術和範式,以便新團隊成員可以更快更高效地上手。
將可支持性作為首要任務聽起來是顯而易見的,因為誰不想要一個易於理解、支持並且易於向新開發人員介紹的系統呢?然而,仍然存在成本和權衡。
基於技術或範式的選擇是否為大量專業人員所熟知,可能會阻礙架構的許多其他特性。可擴展性、響應性、彈性、可用性、安全性以及系統的許多其他方面很可能會被放在第二位。
例如,考慮需要設計一個處理和存儲交易性和強關係數據的金融應用程式。假設實施該應用程式的團隊熟悉NoSQL數據存儲如MongoDB。雖然MongoDB是一個適合鬆散關聯的文檔型數據的優秀選擇,但它不適合具有嚴格和複雜關係的數據。
對於不同實體之間具有複雜關係且需要臨時複雜查詢來檢索這些數據的數據,通常不太適合像MongoDB這樣的存儲。這類數據通常更適合“傳統”的關係資料庫如Postgres或MySQL。
如果我們將可支持性作為這個應用程式的主要架構驅動因素,最終很可能會導致應用程式失敗,並引發一系列挑戰,最終導致應用程式完全無法擴展,資料庫成為瓶頸(這是常見的問題)。
6 可維護性 vs 彈性和容錯性
一般而言,系統越簡單、移動部件越少,越容易維護。使用的技術和部署環境越少,系統運行和維護的速度和難度越低。
例如,在托管雲運行服務中運行單實例應用程式要比分佈在不同節點、不同集群、雲區域和地區的分散式集群應用程式更容易維護。一些組織甚至通過跨多個雲環境部署其系統來確保業務連續性、容錯性和災難恢復(迅速流行但有些爭議的多雲模式)。
由於每個雲(Azure、AWS、GCP、IBM、Oracle等)提供商都有一套獨特的功能、部署模型和機制,在多個雲上維護一組應用程式成為一個顯著挑戰(通常是無法維持的)。
7 找到平衡點
上述的三個架構權衡示例可能更偏向極端情況。然而,它們代表了許多團隊和組織在規劃和選擇正確的架構權衡路徑時所面臨的一些非常現實的挑戰。
好消息是,您不必在二者之間做出選擇。軟體架構權衡以及軟體開發的現實要更加複雜,實際上是一個選擇的漸變。在這裡,您可以選擇在一定程度上實現可擴展性,同時在一定程度上實現簡單性和互操作性。
關鍵在於如何找到不同架構特性之間的平衡,以及如何做出知情的、有意識的選擇。
8 有意識地瞭解架構權衡
如我們在開頭所說,許多,甚至可以說大多數組織,都是無意識地做出權衡。這往往導致這些組織做出錯誤的權衡,給其業務和底線帶來長期且不利的影響。
依賴數字系統的企業必須有一個適當的計劃和流程來做出軟體架構和技術決策以及權衡。在沒有建立正確的架構權衡意識的情況下,這些組織承擔著不合理的風險,其影響和可能顯著減緩組織進展的概率很大,在最壞的情況下甚至可能造成無法修複的損害。
接下來的部分將討論如何進行架構權衡的推理和規劃,以及一些具體和常見的情況。
關註我,緊跟本系列專欄文章,咱們下篇再續!
作者簡介:魔都技術專家,多家大廠後端一線研發經驗,在分散式系統、和大數據平臺設計等方面有多年研究和實踐經驗,擁有從0到1的大數據平臺和基礎架構研發經驗,對分散式存儲、數據平臺架構、數據倉庫等領域都有豐富實踐經驗。
各大技術社區頭部專家博主。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。
負責:
- 中央/分銷預訂系統性能優化
- 活動&優惠券等營銷中台建設
- 交易平臺及數據中台等架構和開發設計
- 車聯網核心平臺-物聯網連接平臺、大數據平臺架構設計及優化
目前主攻降低軟體複雜性設計、構建高可用系統方向。
參考:
本文由博客一文多發平臺 OpenWrite 發佈!