重構有利於項目的健壯和精簡,平時要養成重構的好習慣,“小步快走”,儘量避免留著統一重構的思想,積累很多技術債後重構精力、時間成本很大,風險也會大很多 ...
一、項目背景
為什麼需要架構升級
- promise時效包含兩個子系統:內核時效計算系統(系統核心是時效計算)和組件化時效系統(系統核心是複雜業務處理以及多種時效業務聚合,承接結算下單黃金流程流量),後者依賴前者,分別由兩組技術團隊支持;因為有些業務的滲透造成兩個系統的邊界越來越不清晰;有些需求從PRD評審到項目上線,需要兩組研發全程參與,耗費大量人力;
- promise時效計算業務邏輯經過多年的沉澱越來越複雜,時效計算系統中有很多業務邏輯,導致計算內核也需要跟隨需求頻繁更新;
- 時效計算分為預約和非預約,下單前和下單後,結算頁時效和商詳頁時效。有共性也存在差異,導致共用一部分內核計算的同時存在大量冗餘重覆代碼,需要同時維護和存儲兩份時效計算的緩存數據。
- 多種業務從內核系統中提供專用介面,導致系統嚴重腐化。
- 存在部分未採用RPC方式的依賴,導致jar包依賴和時效計算的切量開關需要配置在組件化時效系統中,影響開發和聯調效率。
綜上,決定這次技術驅動的重構,需要架構升級解決系統中存在的問題。
重構目標
業務邊界更清晰
重構之後的需求邊界從產品側就能夠確定,如果新增倉配時效計算規則需要修改或新增內核計算,其他業務的需求基本組件化時效中修改即可;
業務邏輯更聚合
組件化中整合業務邏輯;
內核計算邏輯更純凈
一套時效計算緩存,節省一半硬體資源費用;
增加系統復用性,一套計算模式同時支持預約和非預約兩種模式,支持結算和商詳,下單前和下單後的場景;維護一套內核計算邏輯代碼,與具體業務分離,節省更多人力資源;
二、方案設計
內核計算業務梳理
現有業務介面:
- 標準達日曆:考慮控單,產能,大宗禁止 標準達日曆
- 京準達日曆:考慮控單,產能,大宗禁止 京準達日曆
- 無人車日曆:無人車日曆 倉自提/無人車日曆
- 倉自提日曆:倉自提日曆,不走干支線 倉自提/無人車日曆
- 自提日曆:獲取自提點四級地址,考慮控單,產能,大宗禁止 標準達日曆
- Vxp日曆:考慮控單,節假日,大宗禁止,不考慮產能,固定最大天數和可選天數 標準日曆
- 7Fresh日曆:標準達日曆計算完成後根據門店波次替換日曆波次 標準達日曆
- 全球購報稅日曆:加上全球購報稅備貨buffer後走標準達日曆計算 標準達日曆
- B2B日曆:B2B日曆計算
- 奪寶島日曆:奪寶島日曆計算
根據業務特點,將原來的8種業務時效計算介面聚合為3個核心通用計算介面,消除了5種業務的特殊處理介面。重新定義設計新的內核計算介面:京準達時效、標準時效、倉自提時效。減少了大量重覆代碼,避免改一個需求就要改好多相同的地方,便於統一管理。
新core系統三個核心介面方法可以為多個業務系統提供服務
系統重構相關業務如下圖所示,
主要變更點:
- core介面聚合,組件化系統適配,補充處理前置信息;
- 重構之前控單介面的調用和產能邏輯分散在組件化時效和base系統中,重構後產能提供新介面,控單和產能邏輯從core系統剝離,集中到組件化時效系統中;
- 大宗商品、二級倉、全球購清關、VXP節假日等業務邏輯上浮到組件化系統,減少了系統間報文大小和介面複雜度;
系統重構業務
三、項目實施
組件化業務梳理
- 考慮產能
- 考慮控單
- 考慮走干支線
- 判斷是否大宗
- 新增全球購清關時長加buffer
- 新增產能白名單
- 新增產能白名單打標
- 新增自提波次格式轉換
- 新增二級倉出參信息整合
- core新介面轉單據類型
- 節能補貼增加預設buffer
- 增7鮮門店波次轉換
- 新增全球購多倉屏蔽邏輯
組件化時效中對新介面進行適配,可用切量開關進行控制
四、穩定性保障
怎樣保證系統重構的安全性和準確性,重構前後一致性驗證上線前主要有兩種方式:單測覆蓋和流量回放驗證;上線後通過多維度切量開關進行控制,保障系統的穩定性。
上線前
- 單測場景覆蓋
1700+個測試用例,覆蓋大部分單一業務場景和部分組合業務場景。
- 流量回放驗證
通過實時引流線上流量,回放到重構後的系統中。流量回放過程中發現差異,分析具體原因,發現多個重構測試用例未覆蓋到的複雜場景問題。
eg.全球購商品滿足城配轉普通時效走大宗時效的場景:正常邏輯是①全球購商品命中了城配邏輯;②全球購不支持城配時效,需要轉普通時效;③轉成普通時效後又命中大宗業務場景。重構時從①走到了③,城配時效和大宗時效是互斥的,所以無法轉換成大宗時效,調整轉換邏輯後導致和重構前時效不一致,這種場景負責涉及業務配置很多,很難通過測試用例覆蓋,流量回放驗證是很好的驗證方案。
- 流量回放自定義對比差異
由於系統架構調整以及新介面的設計和老架構存在差異,導致採購、全球購、控單等業務場景下返回的起始日曆日期不一致,實際可用日曆和波次是一致的,所以這種是預期內的差異,導致流量回放時diff率較高,頁面配置的忽略欄位無法滿足我們的需求;
首次採用自定義腳本進行差異對比,自定義實現排序和忽略項設置,將不影響時效的差異對象忽略掉,減少diff干擾。
- 業務方案確認
對未通過測試用、流量回放差異,研發測試分別列出清單,研發、測試、產品組會進行溝通,對系統現狀和業務影響範圍進行評審,確定最終處理方案。
測試中發現的問題驗證修複後,確認達到業務要求和上線標準,才可以灰度上線。
上線後
灰度發佈時,只接入一小部分流量,並及時跟蹤和分析線上的 log 與監控告警,並關註用戶反饋一有問題及時解決。當新系統趨於穩定時,逐漸加大灰度發佈的範圍和接入的流量,同時繼續跟蹤線上 log 與監控告警。
- 白名單驗證
上線後用白名單用戶進行驗證。
- 流量切換控制
系統上線後,支持用戶PIN的百分比進行切量,灰度驗證實現平穩過渡。
- 組件切換開關
新老邏輯組件可以一鍵切換,如發現問題可快速切回原邏輯,快速止損,保證線上系統安全;
五、項目價值
系統優化
- 按項目預期實現了全新純凈的時效內核計算介面,內核系統具有更高的復用性;
- 組件化系統中重新組織部分邏輯,增加上浮的業務邏輯。系統邏輯更聚合,提升易讀性、減小了系統維護成本;
- 降低上線風險,重塑業務邊界後,交互系統邏輯更集中,減少了相互依賴配置,更利於把控風險;
- 重構修複測試用例和引流驗證時,發現並修複多個線上BUG,保障並提高了系統的穩定性;
◦ 測試用例發現5個BUG,修複遺漏邊緣業務邏輯和處理邏輯錯誤等問題;
◦ 流量回放中發現7個BUG,修複530標位、京準達時效類型等線上bug;
- 修正40+個測試用例;
遇到的困難
系統重構總能留下比較深刻的印象,不僅會碰到技術的挑戰,需要思考用什麼方案更合理;也會碰到難以理清的業務邏輯,需要將產品、研發、測試搖到一起追思憶往;還會發現歷史的“bug”,讓人糾結要不要“更正”;都很耗費發量。
1、流量回放階段,由於出參數據填充方式變化,導致無法比較,通過自定義腳本的方式解決。
2、自提時效多倉場景新架構無法支持,協同產品、業務優化原有多倉場景的處理方式,既解決問題又優化了線上處理邏輯。
項目總結
重構有利於項目的健壯和精簡,平時要養成重構的好習慣,“小步快走”,儘量避免留著統一重構的思想,積累很多技術債後重構精力、時間成本很大,風險也會大很多。如果重構任務艱巨,需要提前做好迭代計劃,重構方案設計之初就要考慮如何分階段實施,小步快走層層分離的策略就相當於搭建施工現場的腳手架,是一種把風險控制在可接受範圍的有效手段。更多關註“明天價值”,當發現好的數據結構、好的思想的時候,甚至一個變數名或方法名,把以前寫的代碼重寫一下;
何時進行重構最好遵循“三次法則”,如果一件事需要做一兩次,可以不著急重構;但是如果需要重覆三次甚至以上的話,就該考慮著手去重構了,保持系統的健康狀態。
公司業務在快速發展中,系統重構期間,需繼續保持業務需求的迭代速度,可以適當增加人員。
系統重構前需要對業務足夠熟悉(包括邊緣業務),重構時可能會遇到看著重構代碼一樣,實際代碼的執行順序影響業務的前後依賴或優先順序,最後影響結果的輸出,在複雜的業務處理流程中很難發現問題。
上線後跟蹤系統運行實際性能變動、資源消耗、穩定性。重構中發現了系統中存在相似的業務處理邏輯、城配相關的邏輯過於複雜等問題,下一步與產品業務溝通是否可以進行精簡,重構不是終點,更像是起點。
作者:京東物流 崔海君
來源:京東雲開發者社區 自猿其說 Tech 轉載請註明來源