如何把複雜單體應用快速遷移到微服務
作者:彭展旋,來自金蝶隨手記的後端開發工程師,目前做專案管理相關工作,逐漸轉型架構,在服務化、分散式事務、p2p金融系統設計、網際網路資訊系統等領域有相關經驗。
從我接手過的一個專案說起。先上一個無關緊要的圖提提神:
隨著專案快速迭代,專案程式碼變得臃腫,資料表已經接近一百張了。其中部分模組程式碼消耗cpu和記憶體大,十幾個開發人員在同一個工程裡面同時開發著十來個特性,系統如下問題凸顯:
1、特性耦合,發版困難
往往一個特性的改動,會牽涉到若干模組,多個特性程式碼改動重疊,給測試以及合板,發版帶來了極大的考慮,降低了發版的效率。
2、非彈性部署,擴充套件能力差
有些模組需要消耗大量cpu和記憶體,有些模組需要支援高併發,有些模組需要很少的伺服器資源,由於都在單一的系統中,各個模組之間公用同一套伺服器資源,分配不均衡,不能針對具體業務進行合理配置擴充套件。
3、系統業務複雜,接手專案困難
在單一的系統中,涵蓋了眾多的業務,一個新入職的同事,花三個月可能都未必能熟悉所有的模組,模組間的各種耦合更是讓人傷神;不敢輕易調整程式碼,修改一個問題極易引發另外一個問題。
4、技術升級困難
由於在同一個專案中,技術架構單一,引入一個新技術對所有模組均會有所影響,調整難度極大,增加技術升級風險,整體技術成保守狀態,難以升級以適應快速發展的網際網路技術。
為此,服務化拆分提上了日程,喵~
服務化拆分流程
在摸透系統裡面所有的業務和資料庫的前提下,我們才可以進行服務化的拆分。由於該系統在線上運營時間較久,在參與系統遷移的同事繼續迭代了若干需求和線上問題跟進之後,對整個系統的業務都瞭解的前提下展開服務化拆遷工作。
先梳理各個模組的資料模型,然後確定每個模組的職責,從而可以梳理清晰各個服務的邊界。
1、解耦老系統外部關聯
實際的業務場景和系統互動異常複雜,在這裡我簡化成以下模型進行說明:
根據確定下來的服務的職責和邊界,建立新服務程式和資料庫,在新服務中約定B、C介面,把老系統中對外依賴A全部轉接到新系統,新系統通過編寫的路由器,把請求路由到老系統。
之所以把外部系統關聯解耦放在第一位,是因為外部系統對接需要協調對應的專案組配合整改,週期不可控,需要先把這部分不可控的先完成上線,方便後續系統內部模組快速拆解上線。
2、解耦老系統模組間關聯
把老系統模組間直接呼叫A,提升到rpc或者http呼叫B,對外暴露介面,打斷原有模組間業務層或者資料層的直接呼叫;
原有系統資料庫sql關聯查詢需要按照模組進行拆解,避免跨模組表關聯操作;
3、程式遷移到新系統
按照模組,把相關程式遷移到新系統。
在做解耦老系統模組間關聯和程式遷移的時候,需要對老系統業務有深刻的掌握,清晰資料庫所有表和欄位的作用,以便能快速遷移。
4、老系統資料全量遷移
把老系統中的所有資料,通過指令碼直接遷移到對應新的資料庫中。至此,所有業務資料的寫入和讀取都是基於新服務的資料庫了,從把老系統遷移到了新系統。
關於服務化拆遷的灰度上線
根據系統的業務,制定對應的灰度上線策略。由於我們系統整個業務是圍繞著產品來開展業務的。所以可以在灰度釋出(金絲雀部署①)的時候,釋出灰度測試產品,將白名單使用者流量打到新版本的伺服器分組上面進行驗證。待驗證沒有問題之後,再逐步開放給全量使用者。
在驗證期間,舊版本如果需要繼續流入業務資料,所產生的新的和改動的業務資料需要再次增量遷移到新資料庫中。這樣會增加增量資料遷移的工作量,容易出錯。我們在升級的過程中停止了老版本系統業務資料入庫:
其中灰度測試使用者產生的資料只存在於新資料庫中。
如何給快速迭代的系統進行拆分
一般網際網路企業版本迭代速度都比較快,所以系統遷移的速度一定要迅速。如果週期太長,一個大的需求下來,系統改的面目全非系統遷移的相關工作就得重頭再來了。
為了能儘快推進系統拆分,總結以上流程,我們要考慮如下五個步驟:
-
需要外部專案組配合的事情先處理完:建立新服務,進行依賴遷移(遷移外部系統介面依賴,遷移外部訊息依賴);
-
介面系統內模組間依賴,定義好服務的職責和邊界;
-
快速遷移模組到新服務,同時進行資料遷移,進入灰度測試環境;
-
灰度測試驗證完畢,遷移增量資料到新資料庫,全量使用者遷移至新系統;
-
線上穩定後,下線老系統,回收相關運維資源。
遷移之後要繼續完善的事情
-
跟上服務化技術配套:服務拆分之後,系統的運維需要輔助額外的代價,維護和測試難度幾何級別增加,我們必須要對應的配套技術:自動化測試,持續整合,自動化部署,配置中心,任務中心,日誌監控等;
-
分散式一致性事務問題:為了解決此類問題,我們可以通過業務補償、可靠事件模型,TCC模式進行開發。
系統遷移工作中帶來後續工作的啟發
-
即使是沒有做服務化拆分,系統間各個模組也要職責邊界定義清晰,梳理清晰業務模型,保證模組間的低耦合,以及模組的高內聚;
-
儘量避免過多的資料表關聯查詢,把資料庫當成儲存資料的介質,業務邏輯轉移到程式中實現,這也為後續分庫分表,服務化拆分做好了準備;
-
提前準備服務化配套技術,重視底層平臺大家。強大的底層平臺支撐,幫助我們填平前人已經踩過的坑:灰度釋出,服務升級回退,服務註冊發現,熔斷降級,自動化部署等;
-
服務化之後,新技術儘量從邊緣業務進行嘗試,積累相關的遷移,服務化,運維問題,構建了一套相對完善的方案,行程一整套技術規範之後,再推廣至核心業務中,方便了新技術的佈道;
附錄:
① 金絲雀釋出:https://www.v2ex.com/t/344341
如何實現灰度釋出:https://mp.weixin.qq.com/s?src=11×tamp=1528615037&ver=928&signature=bPiBMM-FLNAqT4AY3lHouaIpQfEbQHhBIPGMaRu-SLWGX37SjyRdgZsJM5PgHPZsULfEDr*Rl9clTrGVF8tYKz4bZJCA-k-r5*DhDO4Bd-ueXdmuo0*nkz1MaMX7XZp9&new=1
產品角度看待恢復釋出:https://mp.weixin.qq.com/s?src=11×tamp=1528615037&ver=928&signature=TtupdOFeY0ob09qrmdu3OQePeGw4qqQBkk-POiyvMs05sqwGlUb8od1IAV14NKqMZn3BVyfbPs-pTvoOiAvxusWWrDSoJl3BYWTM6yg1tj3NngRFLMqCbWGiFysTERLo&new=1