系統架構設計之可維護性和可演化性
可維護性
軟件大部分成本其實不在最初開發階段,而是在于整個生命周期內的持續投入,包括維護與bug修復,監控系統來保持正常運行、故障排查、適配新平臺、搭配新場景、技術缺陷完善及增加新功能。
可惜許多程序員不喜歡維護這些所謂的遺留系統,例如修復他人埋下的bug或使用過時的開發平臺或被迫做不喜歡的工作。每個遺留系統總有過期理由,所以很難給出通用建議該如何對待它們。
但換個角度,可從軟件設計時就開始考慮,盡可能減少維護期的麻煩,甚至避免制造出易過期系統。為此,需特別關注軟件系統的三個設計原則:
- 可運維性方便運維團隊來保持系統平穩運行。
- 簡單性簡化系統復雜性,使新工程師能夠輕松理解系統。注意這與API的簡單性不同
- 可演化性后續開發能輕松對改進系統,并根據需求變化將其適配到非典型的場景,也稱為可延伸性、易修改性或可塑性
類似可靠性、可擴展性,實現這些目標也沒簡單解決方案。但我們首先還是要建立對這三個特性的理解。
1.可運維性:運維更輕松
“良好的操作性經常可以化解軟件局限性,而不規范操作則會輕松擊垮軟件”。雖然某些操作可以而且應該自動化 ,但最終還是需要人工執行配置并確保正常工作。
運維團隊對保持軟件系統順利運行至關重要。優秀團隊通常至少負責:
- 監視系統健康狀況,井在服務出現異常狀態時快速恢復服務
- 追蹤問題原因,例如系統故障或性能下降
- 保持軟件和平臺至最新狀態, 如安全補丁
- 了解不同系統如何相互影響,避免執行帶有破壞性的操作
- 預測未來可能問題,并在問題發生前解決(例如大促之前就完成機器擴容)
- 建立用于部署、配置管理等良好的實踐規范和工具包
- 執行復雜的維護任務, 例如將應用程序從1個平臺遷移到另1個平臺
- 建立用于部署、配置管理等良好的實踐規范和工具包
- 配置更改時,維護系統的安穩
- 制定流程,規范操作行為,并保持生產環境穩定
- 保持相關知識的傳承(如對系統理解),及時復盤存檔。如發生團隊人員離職或新員工加入
良好可操作性意味著日常工作的簡單,使運維團隊能專注更高附加值的任務。數據系統設計可以在這方面貢獻很多, 包括:
- 提供對系統運行時行為和內部的可觀測性,方便監控
- 支持自動化, 與標準工具集成
- 避免綁定特定機器,這樣在整個系統不間斷運行的同時,允許機器停機維護
- 提供良好的文檔和易于理解的操作模式,諸如“如果我做了X,會發生Y”
- 提供良好的默認配置,且允許管理員在需要時方便修改默認值
- 嘗試自我修復,在需要時讓管理員手動控制系統狀態
- 行為可預測,減少意外發生
2.簡單性:簡化復雜度
小軟件項目通常能寫出簡單而漂亮的代碼 ,但隨項目變大,就越復雜和難理解。這種復雜性拖慢后續的開發效率,增加維護成本。一個過于復雜的軟件項目被稱為大泥潭。
復雜性有各種表現方式:
- 狀態空間的膨脹
- 模塊緊耦合
- 令人糾結的相互依賴關系
- 不一致的命名和術語
- 為了性能而采取的特殊處理
- 為解決某特定問題而引人的特殊框架等
復雜性使維護變得越來越困難, 最終導致預算超支和開發進度滯后。對復雜軟件系統,變更而引人潛在錯誤的風險會顯著增大,最終開發人員更加難以準確理解、評估或更加容易忽略相關系統行為,包括背后的假設,潛在的后果,設計之外的模塊交互等。而降低復雜性就能大大提高軟件可維護性,因此簡單性應該是構建系統的關鍵目標之一。
簡化系統設計不代表減少系統功能,而意味著消除意外方面的復雜性,有大佬把復雜性定義為一種“意外”,即它并非軟件固有、被用戶所見或感知,而是實現本身所衍生出的問題。
消除意外復雜性最好的手段之一是抽象。好的設計抽象:
- 能隱藏大量實現細節,并對外提供清晰易懂的API
- 可用于各種不同的應用程序。這樣,復用遠比多次重復實現更有效率
- 也帶來更高質量的軟件,而質量過硬的抽象組件所帶來的好處,可以使運行其上的所有應用輕松獲益
例如,高級編程語言作為一種抽象,就隱藏了匯編、 CPU寄存器和系統調用的細節和復雜性。SQL作為一種抽象,隱藏內部復雜的磁盤和內存數據結構及來自多客戶端的并發請求,系統崩潰之后的不一致等問題。當然了,使用高級編程語言最終也沒有脫離匯編代碼,只是井非直接使用,與匯編代碼打交道的事情已由編程語言抽象為高效的接口代替我們來完成。
但設計好抽象很有挑戰性。在分布式系統領域中,雖然已有許多好算法可參考,但很多時候并不太清楚如何利用他們,封裝到抽象接口中,最終幫助將系統的復雜性降低到可靠控的級別。
日常開發時,我們可以廣泛考察如何設計好的抽象,這樣至少能夠將大型系統的一部分抽象為定義明確、可重用的組件,提高自己的年終績效!
可演化性:易于改變
沒有一成不變的系統需求,想法和目標在不斷變化:適配新外部環境,新用例,業務優先級變化,用戶要求新功能,新平臺取代舊平臺,法律或監管要求變化,業務增長促使架構演變等。
組織、流程方面 ,敏捷開發模式為適應變化提供了很好參考。敏捷社區還發布了很多技術工具和模式,以幫助在頻繁變化的環境中開發軟件,例如TDD和重構。這些敏捷開發技術多數還只是針對小規模、本地模式(例如同一應用程序中的幾個源代碼文件)環境。我們需要探索在更大的數據系統層面上提高敏捷性,系統由多個不同特性的應用或者服務協作而成
我們的目標是可以輕松修改數據系統,使其適應不斷變化的需求,這和簡單性與抽象性密切相關:簡單易懂的系統往往比復雜系統更易修改。我們將采用另一個不同的詞指代數據系統級的敏捷性:可演化性。
本文轉載自微信公眾號「 JavaEdge」,可以通過以下二維碼關注。轉載本文請聯系JavaEdge公眾號。
































