今天,剛哥要帶來的去年在柏林舉行的GOTO2019的一場關於架構的分享。
演講者Stefan Tilkov是INNOQ的創始人之一,這場分享的主題是「剛剛好」的軟體架構。這這場分享中,Srefan利用一些實際的用戶案例來探討什麼是剛剛好的軟體架構,非常值得我們學習。
軟體架構的定義
首先什麼是軟體架構呢?
這裡最值得注意的是Grady Booch提到的,架構表示重要的設計決定,這些決定定義了系統,重要性是以改動的代價來衡量的。剛哥以為,軟體的架構和軟體的生命周期息息相關,好的架構應該能夠服務整個軟體的生命周期,為未來可能發生的變化和演進提供強有力的支撐。
架構不是負責人告訴其他人該做什麼的前期活動, 架構是系統的屬性,而不是對預期設計的描述。
架構是系統的屬性,你的系統決定了你的架構,而不是你的架構描述了你的系統。
並不存在最好的架構,就像下面的這些車子。
軟體產品有很多的質量屬性,不同的產品需求引入不同的質量屬性,不同的質量屬性定義了不同的上下文環境,也就會有不同的架構選擇。
如下圖所示,我們可以從兩個規模維度來分析軟體系統的,水平維度是系統的複雜性,垂直維度是系統的用戶數量。不同的系統從規模的角度來看,處於不同的位置。
所以,離開上下文環境來說,並不存在所謂「好的」或者「壞的『軟體架構,架構設計需要考慮特殊的質量屬性。
下面,就從一些實際的案例來看看。
案例一:不可擴展的擴展性
第一個案例是一個零售業的電商平台的例子。
上下文環境
- 平台服務全球用戶
- 服務包含Catalog/CMS/Shop
- 多租戶
- 高度客戶定製化的需求
該平台的用戶分為兩類,一類是小用戶,使用一些常見的通用功能,還有一類的大用戶,需要非常特殊的客戶定製功能。
我們從成本的客戶定製化兩個角度來看,對於小的用戶而言,只需要提供一些通用的功能,而對於一些大用戶而言,需要提供非常特殊的用戶定製,當然這樣做帶來相應的成本的提升。從實際的實施來看,該系統提供了一個折衷的方案,提供了一些定製化的功能,希望同時能夠服務兩類用戶。其實這樣的設計既不能滿足大用戶實際的定製需要,對於小客戶而言也沒有實際的價值。
從這個案例我們學到的是:
如果你的設計希望滿足所有人的需要,那麼最終可能誰的需要也滿足不了。高度定製化的代碼往往優於複雜的配置。
案例二:危險的細粒度
第二個案例是一個大規模B2B食品零售商
上下文環境
- 新上線公司級的商鋪和物流系統
- 有200+的開發人員
架構決策是採用微服務的方式構建產品,結果是不同的團隊之間有很多的耦和的細小的服務。這些服務變得很難管理。
以訂單服務為例子,所有的其他的服務都會依賴訂單服務。結構訂單服務耦合了所有其他服務的邏輯。
問題來了,為什麼你要把系統切割成很多細小的,分布的,不可維護的碎片呢?
答案是Netflix,Netflix採用微服務架構取得了巨大的成功,但是,不是每個產品都是Nextflix,要構建分布式的可擴展的影音服務。
更恰當的架構是這樣的:
從這個案例我們學到的:
小的並不一定好在團隊的界限之內進行重構和優化,比從全局來做要容易忽略組織架構的特性來構建架構是很危險的
案例三:系統是動態的
第三個案例是一個大規模的保險系統
上下文環境
- 模型驅動的設計
- +100的開發人員
- 每年兩個release
該項目的開發過程中存在一個兩周的模型設計過程。
骨灰級的程式設計師大概還記得rational rose,那個曾經非常火爆的建模工具。
其中一個版本,需要把一個模型的某一個欄位改名。
這個欄位的修改是維護在一個龐大的Excel表格中,可以想像這個修改會帶來的代碼的變動,就像噩夢一般。因為模型的所有其他工作的基礎,模型的改變是你絕對不想觸及的東西。
從這個案例我們學習到的:
中心化的責任會是痛苦的 (這裡例子了就是建模的人)當系統的規則很刻板的時候,開發人員會採用一些迂迴的方案你所習慣的東西不代表它是正確的
案例四:自由式的架構
第四個案例是一個零售業的電商
上下文環境
- 100-120個開發人員
- 10個自包含的團隊
如下圖所示,我們常常說的系統的解耦合往往和開發人員的數量相關的。
隨著開發人員的增加,我們往往需要結偶的方法,模塊,組建,服務甚至系統。
從分層的系統演變為包含子系統的系統。
在這裡案例中,架構設計是引入前端的微服務架構。
但是問題也隨之而來, 該產品的執行策略是一種自由的方式,而該自由方式帶來了如下的問題
- 缺乏開發標準導致UI集成的低效
- 大量API風格,格式,文檔的差異導致了額外的工作量
- 雖然不存在中心化的前端UI組件,但是存在一個中心化的前端UI團隊, 該段對成為了系統的瓶頸
從這裡案例我們學到:
你無法決定不定義架構,如果你不積極的去創建它,它會自己出現,準備好去應對它。要明確多樣性和混亂的界限極度解耦合的系統需要少量的規則,但是這些規則需要強制執行
案例五:像癌細胞一樣生長
第五個案例是一個獨立財務服務提供商
上下文環境:
- 30的開發人員
- 公司有20年的歷史
- 該產品非常成功
剛開始結構比較簡單,使用orcale資料庫和Orcale Forms App。
隨著產品發展,他們決定改進架構,引入Java/JSP Web引擎
然後系統引入了.net的Web技術
隨後,他們收購了另一個公司,所以有了兩套系統,但是他們決定使用同一套資料庫系統。
隨著系統演進。更多的資料庫被引入。
最為有趣的,他們用C++實現了一個加密的算法,但是該算法出錯了,但是沒有辦法修復,因為數據已經用出錯的算法加密了。
但是因為產品的商業上很成功,於是沒有人介意這些架構上的問題。系統像癌細胞一樣野蠻生長,隨著他的長大,清理也變得非常困難。
從這個案例我們學到:
成功的系統可能擁有糟糕的架構缺乏管理的演進可能導致混亂不要害怕引入輕微的架構約束
案例六:利用少量的智能來改善系統架構
最後帶來一個成功的案例。一家擁有多個COTS系統的銀行。
上下文環境:
- 高度私有化的集成方案隨著廠商需要退出使用
- 利用開源解決方案替代已有的商業解決方案
系統主要的挑戰是存在很多的集成的需求。
他們利用消息總線,很好的解決了這個問題。
從該案例我們學到的:
- 智能端點和傻瓜管道
- 定製化的價值優於通用解決方案
- 帶有藍圖的微架構
總結
Stefan最後做出了如下的總結:
- 不要害怕架構
- 選擇最簡單的可工作方案
- 創建可演進的結構
- 管理你的架構演進
- 不要引入路障,關注價值的創造
剛哥的解讀,該演說利用一些實際的案例來講述什麼是「剛剛好」的架構,其中一些問題是我們在軟體開發過程中經常會遇到的問題。很具說服力。但是因為時間的原因,細節講述的比較少。我這裡把大體的內容帶給大家,大家有興趣的話可以去看視頻。
這裡有PPT : https://github.com/gangtao/confshare/blob/master/GOTO2019/2019-10-23-Good-Enough-Architecture--GOTO.pdf