背景
我所在的部門其中重要的一項工作就是對接社區項目新的業務需求,社區項目已經維護N多年了。到14年初的時候社區的解決方案中已經有一百多個工程,每打開或編譯一次解決方案都需要等很長的時間。當時就出現這樣的情況,幾乎沒有項目經理能夠面面俱到的理清楚社區解決方案的所有代碼。同時,在現有社區上做簡單修改也是一件很麻煩的事情,而且每次升級社區都會很危險,整個社區項目正在走向腐朽。在這樣的情況下,部門總監決定對現有社區項目遷移為分布式系統。
為什么是分布式系統
社區之所以代碼量大是因為業務邏輯多、雜並且多種業務之間的代碼相互引用,所以明確業務主線、分拆業務主線、降低業務主線之間的耦合度成了首要的任務。分布式系統恰巧能很好的為分拆業務主線,協調業務系統交互提供友好的指導。
最終社區分拆為游戲、計費、安全、推廣、賬號五大業務系統。每個系統提供UI功能站點(UI功能站點的特點是提供可供用戶使用的功能界面,並且包含業務邏輯實現),同時為了便於其他業務系統使用其業務邏輯,每個系統還需要提供業務服務站點。服務站點分為兩類,一類是可調用其他服務站點的interface站點,還有一種是不可調用其他業務系統的module站點,這樣做的主要目的是為了使接口站點、頁面站點的調用關系清晰,便於以后的開發和維護。
遷移中可預見的問題
由於社區是線上系統,所以大的改動會帶來發生線上故障的風險。同時在遷移過程中產品部門會不斷的提出新的需求,產品的需求的優先級非常高,換句話說我們一邊要做遷移的工作一邊還要對接新需求。最重要的是部分代碼的代碼結構會變,簡單的代碼合不能夠解決問題,某個時間段內需要對接兩份代碼。當然我並不是在叫苦,我只是想說整個遷移的過程會很痛苦。
遷移過程
第一階段
這一階段的主要任務是分拆代碼,將每個子系統原有的代碼移到新的解決方案中,如果需要調用其他子系統的代碼則跨解決方案引用老的工程。這一階段特點是不對對現有的代碼做太多的改動,只是簡單的把之前的代碼移到新的工程里並改動類的命名空間,在這一過程中如果有新的需求需要對接兩份代碼。這一階段開發完成后,需要QA人員測一遍所有業務流程並將新代碼編譯的組件上傳到生產環境。
第二階段
這一階段的主要目標就是由引用老的工程改為調用其他業務系統提供的接口並為其他系統提供接口。首先,以業務系統為單位,找到所有引用其他業務系統的代碼,並整理成文檔。緊接着就是在會上相應子系統的項目經理記錄都有哪些系統用到自己負責的系統,並記錄調用自己功能的業務流程,還需要消化並剔除重復的需自己提供的接口。接下來的工作就是提供接口了,各個系統的開發人員開發相應系統的接口。這一階段開發完成后,需要QA人員測一遍所有業務流程並將新的代碼上傳到生產環境。
為了便於其他系統的接入,每個接口站點需要提供一個SDK,SDK的主要工作就是為調用網絡接口和將返回值映射為.NET對象,這樣一個子系統想使用其他系統的功能就非常方便,這也是社區為SOA中高互操作性做的努力。
這樣保持業務的事物性
當各系統的QA人員測試完個接口的功能和壓力之后,各系統供用戶使用的UI站點就需要移出對老工程的引用,改為調用相應的接口了,這時候我們碰到一個問題,就是現有的系統不能夠支持事物,本來想引入WS-*,但是WS-*效率實在太低了點,結合我們當前實際情況,我們引入了重試以保證每次業務流程都一定能完成,即如果調用相應的業務系統,調用不成功或者業務系統返回的失敗,重試服務就會在兩天之內調用16次相應的接口以保證確保通知到了該系統。
為什么要分為兩個階段
可能有人會問,為什么非要分為兩個階段呢,並且每個階段都需要上生產環境,干嘛不直接改完之后上傳到生產環境。其實這樣做的目的是為了平攤風險,將風險平攤到每個階段。這里的平攤風險並不是上到生產環境就沒風險了,分兩個階段遷移,每一階段的故障要低於無階段遷移,避免因線上問題過多而導致必須回滾生產環境版本的情況發生。
末尾
社區遷移完成之后,研發的並行度提高了,每個系統可以單獨進行伸縮。從項目經理的角度來看,負責的業務流程和項目清晰明確。從開發人員的角度來看,所面對的項目不復雜。所以說不管是從項目上講還是從管理上都達到了松耦合目的。