分享一個真實的重構案例
寫在前面
想想為什麼要做重構?
如果沒有能說出來的理由,建議不要輕易重構。
機票系統A的現狀
A系統的背景
業務上:從杭州挪到北京,作為重新孵化項目,想要做大做強。行業競爭壓力非常大,做不出成績,項目就會被斃。
技術上:遺留的老系統,在一個其他系統基礎上改出來的單體,換手了四次團隊,找不到一個了解這個系統的人了。
關係上:北京公司新成立,拿到這個項目,是作為一個大項目來做,也是要樹立起標杆的項目。
當時我寫的一封郵件,描述的這個系統現狀。
中國機票舊系統開發於2006年,期間幾十名開發人員在程式碼里留下了痕迹。不久前移 交到北京新業務研發團隊維護,主要問題有: 1、程式碼量大(40萬行),品質不高,結構複雜,難以修改和維護。一些程式碼的具體作用 和邏輯細節,沒有人清楚。很多注釋和程式碼不一致,文檔缺乏,比較混亂。 2、業務處理過程邏輯複雜,中間數據冗餘,與外部介面耦合度高,性能較差,穩定性 不高,扛不住大促活動壓力。 3、對業務過程的數據和狀態監控不足,難以管理控制和跟蹤,各方使用不方便。 4、剛交接過來,沒有人真正懂這個系統的業務,業務方也是空降,這個問題尤其嚴重
重構面臨的壓力和選擇
當時看來,重做是最好的辦法,但是不現實。
業務方:不能停止業務,否則死路一條
開發方:沒有太多資源,且半年後大促。
只能選擇在老系統基礎上重構。
如何推動重構A系統
一個很常見的衝突點在於:
業務方覺得系統重構不帶來業務價值,說不定還搞出點bug,是有風險的。
你一說其他的,他們就會說「反正還能用」。
對於重構各方都有自己的觀點和要求。
對於業務方來說,要求如下:
- 業務不停
- 保障穩定
- 提升性能
- 快速開發
對於產品方:
- 提升用戶體驗
- 改版引流
- 其他同業務方
對於開發方:
- 資源得到傾斜
- 最大滿足業務和產品需求,同時能夠發展研發團隊
最終各方達成一致,但是研發肯定是壓力最大的。不用怕,在這種臨危受命的同時,可以提要求,定規則。(如果初期不把這些要求提出來,中期再提就沒那麼容易滿足了。)
本著這個目標,提出了如下要求:
- 所有其他項目為這個項目讓路,最高優先順序
- 資源主要用來保障這個項目,所有人配合,包括後面招聘的
- 人員管理等方面,特事特辦,所有人不管考勤等制度
怎麼定重構目標
平衡短期利益和長期利益
1. 分階段
先重構搜索模組,然後是訂單交易、產品庫存。
搜索模組的目標主要有五個:
- 培養機票新人。梳理清楚中國機票搜索部分的業務和各種潛規則,培養懂機票的新 人。
- 提高程式碼品質。設計更合理,結構更清晰更易維護,系統耦合更低、擴展性更高。
- 提升搜索性能。使系統更穩定,更高效,搜索更快,資源消耗更低,大促不宕機。
- 監控搜索過程。統一管理搜索過程中的各種開關和參數調整,管理快取,跟蹤搜索 步驟。
- 中國機票搜索去oracle化。 在搜索重構的過程中,用mysql代替舊系統的oracle數 據庫。
目標的具體說明:
-
培養新人問題,主要是XX\XX\XXX\XXXX。在此過程中,熟悉淘寶技術體系和開發 過程,掌握中國機票業務,能逐步的cover機票系統。
-
程式碼品質問題,主要是項目結構合理的分層,搜索的分段式處理,code review,高覆蓋率的單元測試,使項目易懂易上手易維護。
-
提升性能方面,主要從簡化中間結果和數據結構,理清業務簡化舊邏輯,整理各步 驟快取最大化合理利用快取結果三個方向來提升系統在CPU計算和記憶體、以及網路 IO等方面的開銷。提高系統吞吐量、QPS,降低響應時間。
-
監控搜索過程,通過哈勃、timetunnel+ateye、memlog、系統log等手段埋點,管 理系統多種粒度的開關和參數設置,跟蹤和調試搜索流程中的數據和狀態、各種外 部介面數據和快取。
-
去Oracle,改用mysql+tddl,實現分庫分表,為進一步的分散式架構打下基礎。
2. 變組織
- 架構師主力,長期大辦公室開發,負責核心和全流程
- 其他後備力量,負責業務模組+迭代周期
- 開發期間,試行996(算加班調休),搶在年底大促前完成重構
重構的過程
第一步:規劃
確定規劃,分步改造。
啟動項目,拉齊思想。
- 上線啟動10/11
- 灰度發布10/20
- 功能發布10/27
- 全部提測11/08
- 所有上線11/29
- 機票大促12/21
第二步:明確業務
- 重建業務需求穩定,需求是一切的起始點。
第三步:架構調整
分層改造和逐步對接。
所謂分層改造:就是當時我們的系統分為contrller-> ao -> service -> dao -> db
我們可以改造dao層和db層,將oracle換成mysql,service原有的不動,新創建一個實現類,接新的dao層。這樣老的和新的實現都有,可以隨時切換。
在一個需求周期內,完成業務需求的同時,搭車發布技術改造。
3.1 性能優化
- 從優化業務處理角度。同步大事務到小事務,非同步處理
- 從優化系統程式碼角度。多層for循環的優化
- 從優化數據結構角度。優化掉一個笛卡爾積
- 從優化快取策略角度,從靜態的快取時間到動態計算快取時間。
3.2 引入標準
借鑒之前的ESB經驗,解決對接的複雜性問題,標準化集成方式。
不同航司的介面,差異非常大,數據結構也不同,數據的有效性也不同。
原有的外部對接與業務系統耦合嚴重,對接方式也是五花八門。抽離出一個標準規範,做一套ACS系統來專門對接外部航司的介面。支援更好的橫向擴展和維護性。
3.3 灰度發布
通過灰度發布+特性開關,保障可靠上線。
先是預發環境上線,辦公室內訪問。然後線上灰度,公司內部IP訪問。再接著杭州和北京訪問。最後全國訪問,完全放開。
3.4 監控運維
實現一套全方位的運維繫統,快速發現和處理問題。實現線上開關和debug的機制,快速定位問題。對每天的業務數據進行自動統計和發郵件,做到所有人對業務情況瞭然於心。
最後的效果:
- 業務上,支援了大量新功能,包括營銷促銷系統
- 技術上,重構了新系統,完成了去O和分庫分表,保證了大促
- 產品上,優化用戶體驗,補齊系統的功能短板
- 團隊上,培養了一批懂業務,懂新系統底層的核心研發人員。
新系統文檔完善,架構先進,程式碼只有舊系統1/3不到,性能提升30倍。
(註:以上案例是秦金衛老師的真實重構案例)