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