架構中的矛盾和權衡

文 | 少個分號 (轉載請註明出處)

關注公衆號:DDD 和微服務

微信號:linksgo2016

同名知乎:少個分號

一個週末時間參加了架構大師的 Neal 的架構培訓,由於時差的原因在週末的兩個早晨。課程圍繞着微服務和大型系統,在他的培訓中反覆提到一個詞 “tradeoff” 引起了我的興趣。

因爲我們在討論架構的過程中,總會陷入一些矛盾,這些經典的矛盾成了關於架構無盡爭論的源頭。這些矛盾往往是我們分析架構方法的關鍵所在。

在現實中,企業採用微服務架構的主要動機往往是因爲團隊過大,以至於無法讓數十個、百個人同時在一個項目上工作。這個時候會帶來另外問題,如何讓這些分佈式的系統合適的集成起來成了另外一個問題。

這時候,使用微服務架構是爲了解決一個矛盾:大型團隊超過管理容量和並行開發之間的矛盾。當我們在討論是否需要微服務時,需要關注時候當前有類似的矛盾存在。

例如對於創業公司而言,在 “兩個披薩” 就能喫飽的團隊規模,則還沒有這樣的矛盾,因此使用微服務不一定是一件好事。

架構中的矛盾

架構設計中,有各種各樣的矛盾。

用戶故事的獨立交付和可複用平臺建設之間的矛盾。 在一些大規模的應用中,需要建設一些基礎的業務能力,現在流行叫做 “中臺”。一個基礎業務會被多個場景用到的時候,使用中臺集成這些能力,會給用戶獲得一致的體驗。不過,這種實踐會帶來另外一個矛盾,中臺必須和接入的應用不斷集成。

這會給敏捷團隊帶了一個困擾,因爲敏捷團隊會使用用戶故事(User Story)作爲需求劃分的方法。爲了保證敏捷交付,用戶故事需要遵守 INVEST 原則:

  • Independent 獨立的

  • Negotiable 可討論的

  • Valuable to Purchasers or Users 對客戶或用戶有價值的

  • Estimable 可估計的

  • Small 小的

  • Testable 可測試的

使用中臺後,某些業務能力需要貫穿中臺團隊和應用團隊,就無法由一個團隊獨立完成,也做不到獨立發佈和交付。在某種程度上,這種矛盾難以調和,因此就需要對中臺的團隊修改其協作模式。比如中臺團隊使用看板(Kanban)模式,通過響應應用團隊的業務訴求來提供相應的能力,這就是架構設計中的一種權衡。

另外的典型矛盾還有數據耦合和一致性的矛盾。

在微服務中,數據庫會和服務一起被分離,這種分離會造成一個典型的問題 —— 數據一致性問題。這種問題幾乎無處不在,例如用戶服務和不同的微服務解耦,那麼用戶信息會出現在各個服務的快照或者緩存中,以避免對用戶服務的頻繁訪問。

這就會產生一個矛盾,當用戶數據變更時,其他相關的服務可能得不到實時更新。一般來說,用戶的信息不能同步更新是可以容忍的,以避免用戶服務不可用時,其他服務也能相對健康。

如果架構師過分追求實時更新而忽略了系統的可用性這得不償失。在理論上可以用 CAP 定理說明:

分佈式系統只能在一致性、可用性、分區容忍性之間三選二做出保證:

  • Consistency: 一致性

  • Availability: 可用性

  • Partition tolerance: 分區容忍性

微服務系統天然的選擇了分區容忍性,於是只能在一致性、可用性之間做出保證。這並不是意味只能選擇一致性、可用性,而是說在發生故障時,只能二選一。

在編碼實踐中另外一個矛盾就是,面向對象中,關注點分離和複用邏輯的之間的矛盾。

大量的遺留系統告訴我們,錯誤的複用是讓系統過分耦合的原因之一,這似乎違反面向對象中儘可能的追求複用的原則。這背後的邏輯是:面對大量的應用場景時候,如果沒有足夠的關注點分離,會在 “可以複用” 的代碼中寫出更多的 if 語句。

舉個例子來說,系統可以允許用戶自己註冊,也可以讓管理員來添加,如果他們複用同一個接口,就必須判斷來源,從而進行不同的邏輯處理。反之,通過關注點分離,提供給兩個用例不同的接口,把差異處理後再進行復用,可以大大簡化邏輯。

權衡的原則

權衡的原則之一就是抓住主要矛盾。

主要矛盾是指在架構決策中的諸多要素中最關鍵的、佔據支配地位的矛盾。抓大放小往往是解決架構矛盾的關鍵所在,但是認識到什麼是主要矛盾比較困難,也是做技術決策的挑戰之處。

對於創業公司來說,他們的主要矛盾是快速的迭代和功能演進,可維護性和系統容量並不是其主要考慮內容。因此,微服務一般不是其選擇的主要方向,應該使用一些敏捷快速開發框架,通過模型來驅動快速功能完成。

對於業務已經基本定型,快速成長性的公司來說,他們的主要矛盾是業務的快速擴張和大量人員共同開發的矛盾。在做好微服務的準備和條件下,可以通過服務的拆分,讓加人變得可能。

對於業務已經穩定的公司來說,他們的主要矛盾是如何讓業務持續運行和架構不斷腐化的矛盾。因此他們的技術方案會更加保守,使用成熟可用的方案,並不追求新技術和方案。

拆分微服務的權衡

微服務已經是比較主流的技術方案,對於微服務拆分的權衡來說,可以參考以下幾個方面。

服務的功能。 首先,任何技術方案和決策,都需要有他的適用範圍,微服務也是。對於一些天然可以被拆分的業務來說,可以優先考慮拆分。比如郵件、通知等系統,這些系統本就可以作爲獨立的能力運行。

代碼波動情況。但業務架構不穩定的時候,分佈式系統的調整成本遠遠大於單體系統,這個時候需要考慮單體優先的架構策略。業務架構不穩定的會反應在代碼的波動上,如果軟件模型頻繁調整,不適合拆分微服務。

彈性需求。 不同的業務有不同的訪問頻次,對於彈性需求不同步的業務來說,如果將熱點業務拆分出去可以提高整體的性能和可維護性。

容錯。 如果對系統有特別的容錯需求,也可以考慮拆分微服務,並使用降級和容錯的特性來保障服務之間的相對隔離。

數據安全。 另外一些特殊的需求是來自於安全方面,用戶信息、信用卡信息、賬戶信息和其他業務對於數據安全敏感性不同,也可以考慮使用微服務來保護數據安全。數據安全的保護不僅是系統運營過程中的安全,也有開發過程中的安全。一些專業的公司,會根據數據的敏感性不同,將辦公區域劃分爲不同的區域。

架構驗證方法

架構權衡是一個具有挑戰的工作,因此需要一些架構驗證的方法。

POC 測試( Proof of Concept)。 POC 越來越被重視,其含義是:當我們在設計一個大的系統前,先設計一個原型系統,在原型系統之上進行驗證架構是否合理。

原型方法是軟件開發中比較重要的方法,但我們做一些重要的軟件設計時,先設計原型,通過對原型的檢驗一步一步逼近真實的系統。甚至會有公司進行多個團隊開發原型,使其具有競爭關係,再選擇一個團隊來開發商用系統。

原型設計分爲多個層次:

  1. 商業原型。商業原型一般就是 PTT 演示文檔或其他模型,可以做一些用戶測試,驗證系統在商業上是否可行。

  2. 業務原型。業務原型一般是指用戶的交互和界面,通過藉助 Axure 的界面原型設計軟件設計出軟件應該有的樣子,用於軟件工程師和架構師進一步設計軟件架構和領域模型。

  3. 技術原型。通過實現一個 demo 來驗證技術的可行性,可以通過這個原型來分析技術的各項指標,比如潛在性能問題、安全問題等。

原型法可以用低成本的方式驗證軟件設計過程中的問題,提高軟件開發的成功率。

ATAM 架構權衡分析方法。架構和方案被設計出來之後,需要對架構進行評審。通過架構權衡分析方法 (Architecture Tradeoff Analysis Method,ATAM) 總結了架構評審中的關鍵幾個條件::

  1. 架構的可行性。架構是否可行,能否靠現有的團隊完成實施工作。

  2. 架構的業務支撐性。架構是否能支持現有的業務,尤其是未來一段時間的業務。能在一定程度上響應業務變化的架構纔是合理和實用的架構。

  3. 架構的成本。大的公司的架構不適合小的公司,往往是其成本決定的。比如 Hybrid App 作爲低成本的開發方案可以讓創業公司的產品快速成型,但是對於大的公司來說需要更好的用戶體驗,因此在有足夠投入的情況下會開發 Native APP。

架構權衡分析方法作爲一種專業的架構權衡的方法還提供了一整工具可以選用。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/76yq1ConKgyoE56HehXGJA