原地址:https://www.cnblogs.com/fundebug/p/10734209.html
前言
隨著公司業務的爆炸式的增長,需求規模和用戶規模也迅速地膨脹起來,這樣給系統的三高(高性能、高并發、高可用)以及擴展性、可維護性都帶來了考驗。而舊系統因為早期設計的各種局限性(如早期參與人員的水平、架構設計的前瞻性、老板的急性子等等),逐漸滿足不了現狀和未來的新需求,暴露出各種問題。開發人員們像是拖著老破車上高速,苦不堪言。(說人話:老系統代碼的坑太深了,開發們填不住了,要么被坑埋了,要么棄坑逃跑了…)
那么這個時候,通常要面臨一個問題:是繼續填坑還是跑路走人 選擇重構。填坑是不可能的,這輩子都不可能的。而選擇重構是需要壯士斷腕的勇氣,因為重構是一項老大難、一件耗時耗力的事情,且多少會對現有業務開發造成影響,甚至是停滯。因此大多時候得不到產品經理和老板的支持,他們關心的只有一個:下個需求什么時候能上!至于其他的,都是你們研發該操心的。
自己選擇的重構路,跪著也要走完。如何來一次就干就干的重構呢?根據互聯網常見項目重構流程,以及我的親身參與的重構項目經歷,梳理大中小型系統的常見重構流程如下:
零:說服業務方
重構不單是研發團隊的事情,更是整個項目團隊的事情。重構可以提升系統的三高,也可以優化改善業務流程,滿足新的業務訴求等等。重構需要投入大量資源,必須要得到業務方的支持。通常這個時候需要對他們曉之以理,動之以情,闡述清楚重構的利弊,以及不重構的要害。在得到他們的支持后,重構的工作便正式開展。
參與人員:技術 Leader
一:樹立重構目標,有的放矢
重構是一項工程,是一場持久戰,它不是一兩個迭代、甚至一兩個月能做好的事情,需要投入大量的人力、物力、時間精力等。那么在這場曠日持久的戰斗中,我們的目標是什么?是通過更優秀更合理的架構來滿足系統三高的需求,還是想通過重構來提高代碼質量,或者引入新的技術和框架來升級整個系統,抑或通過重構來優化業務流程,實現原來實現不了的需求。有了目標后,才能做到有的放矢。
參與人員:技術 Leader,架構師
二:確定重構的范圍,并對重構作出預測
重構通常有以下幾個級別的重構
平臺級別重構。針對整體平臺的重構,如阿里早期是 LAMP 架構,后來整體遷移到了 Java 平臺。
系統級別重構。針對業務系統的重構,如通過引入微服務架構或者 SOA 架構,分解單體應用。
架構級別重構。如通過架構的調整和重新設計,改善原有架構的不合理之處。如通過分層使業務解耦,引入緩存設計提升系統高并發等。
業務級別重構。常見為某些業務需求因為系統設計的不合理性導致無法滿足或有缺陷滿足,需要通過業務系統的重構調整或數據庫的重構來解決。
模塊/代碼級別重構。這是最常見的重構。通常指使用設計模式、封裝繼承、優化拆解代碼,使得代碼的結構更良好,運行效率更高。
確定這次重構是屬于什么級別,確定重構的整體范圍的大小,確定重構的技術選型,進而對重構工作進行科學的評測和預估。比如需要投入哪些成本,需要投入的人力和時間是多少,在重構的過程中能否支撐正常業務需求等等。在有了這些預測后,也對業務方有個交代,尤其是當他們追在后面問什么時候能上新需求。
參與人員:技術 Leader,架構師,研發人員
三:舊系統的熟悉和業務梳理
重構不是和舊系統說散就散,而是要不斷和舊系統戰斗的過程。知己知彼,百戰不殆。重構不僅需要清楚新系統的目標和未來,更需要對舊系統非常熟悉(尤其是坑)。此時需要參與重構的人員(尤其是參與舊系統的人員)來對舊系統業務和系統進行梳理,對原有資料信息進行收益和整理的工作,對舊系統的關鍵代碼和數據庫設計進行 Review 等等。
以下是重構舊系統前需要準備的常見工作:
舊系統資料和信息的收集,包含且不限于系統相關的設計文檔和技術文檔等文檔資料,架構圖、UML 圖,數據庫設計 ER 圖等圖形化資料
業務線和業務流程的梳理,整理業務線上的各大項目、業務流程,并輸出為文檔
舊系統關鍵代碼的 Review
有相關疑難點及時與相關與業務線上的人員溝通,將問題解決在”襁褓”中。
參與人員:技術 Leader,架構師,研發人員
四:數據庫重構
如果在重構中需要涉及數據庫的重構,數據庫的重構一般是最先開始的一步。系統需要重構的直接原因,也大多和數據庫有關。在數據庫重構時,我們清楚舊系統中數據庫的各種設計缺陷和使用障礙,那么就可以對癥下藥,如通過三大范式或反范式來設計表,是否需要分庫分表等等。
參與人員:DBA,架構師
五:后臺系統重構
后臺系統重構前,必須需要依照前文所述的一些設計和技術文檔。這些文檔輸出后并經討論成型后,架構師進行系統架構設計,后臺開發人員進行具體編碼工作。通常這個過程是耗時最長的,也是非常重要的一環。后臺的架構設計水平,決定著系統重構的水平,業務代碼的質量,決定著系統重構的質量。
因為這個過程比較漫長,且成果無法立竿見影。所以通常采用敏捷開發的模式,通過迭代的方式來進行后臺系統重構。迭代的方式有幾個好處:
需要將整個重構過程進行有效規劃和量化,做到胸有成竹
每個階段能有可見的成果,確保團隊在長時間的重構過程中不陷于泥潭
對已重構好的部分可以及時進行聯調測試或觀察,不斷在迭代中總結、在總結中迭代
另外在后臺系統重構時,也需要有明確量化的目標和標準,比如各系統和業務模塊支持多少 QPS,接口響應時間多長時間等,這樣團隊才能在重構的過程中不至于為了重構而重構。
在重構過程中,定期進行 Code Review,及時發現重構的問題和質量的問題,避免出現破窗效應,引入拙劣的設計或垃圾代碼,進而破壞整個系統。
參與人員:技術 Leader,架構師,研發人員
六:數據遷移與檢查
如果涉及數據庫重構時,在新的數據庫設計好后,就會有面臨數據遷移的問題。一般分為全量遷移和增量遷移,全量遷移是將舊系統的數據一次性遷移到新的數據庫中,增量遷移是在實行全量遷移后舊系統新產生的數據遷移到新系統上來,增量遷移一直到舊系統下線不再產生新數據后。通常遷移都是通過編寫腳本或程序來實現,拒絕人工操作。
遷移后自然需要對比新舊系統的數據,同樣可以通過腳本或程序來進行對比,查缺補漏,定位分析。
參與人員:DBA,研發人員
七:系統檢查、聯調與測試
在后臺系統重構到一定程度時,同樣也需要編寫腳本和程序來對新舊系統的業務接口進行檢查,及時發現重構中的問題,必要時候進行架構調整和數據庫調整。當然,在重構時,開發人員能提高單元測試覆蓋率當然是更好不過。當各系統和模塊的依賴解決的差不多時,可以開始聯調工作。
當然最后還需要系統性的測試,如功能性測試、穩定性測試、性能測試,本地測試、模擬線上環境測試等。測試中發現的問題經驗證修復后,達到上線的標準,即可灰度上線。
參與人員:架構師,研發人員,測試人員
八:灰度發布與觀察
萬里長征已經走到最后,也到了最緊要的關頭?;叶劝l布時,只接入一小部分流量,并及時跟蹤和分析線上的 log 與監控告警,一有問題及時解決。當新系統趨于穩定時,可以逐漸加大灰度發布的范圍和接入的流量,同時繼續跟蹤線上 log 與監控告警。
參與人員:運維人員,測試人員,研發人員
九:系統切換
在系統切換時,需要提前制訂系統切換方案,包含相應的規劃與流程,甚至是應急預案與回滾方案,避免走一步看一步。切換完成后,新系統完全替換舊系統,舊系統下線,完成重構。
參與人員:運維人員,測試人員
結語
通過上述幾個步驟后,我們成功對系統進行重構。
重構是一項大工程,但經歷重構后的系統也并非完美無缺。重構不是終點,更像是起點。