天天看點

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

對一個程式員來說,世界上最痛苦的事情是什麼呢?

有的人會說:編碼的時候産品改需求!

有的人會說:看别人不知所雲的代碼!

有的人會說:定位一個百年不遇千年難尋的線上不定時偶爾出現的bug!

有的人會說:找不到女(男)朋友!

。。。。。。。。。。。。。。。。。。。。。。。。。。

但我要說,這些痛苦其實都不算什麼,要麼是多花點時間去解決(比如說改需求、看代碼),要麼是多花點心思(比如說找另一半、定位疑難bug),而我接下來說的這個事情才是最痛苦的,既要說得動老闆,也要鎮得住同行;既要技術攻關,又要協調資源;既要保證業務正常發展,又要在指定時間内完成目标。。。。。。總之就是十八般武藝要樣樣精通。

 這個事情就是“架構重構”,比“架構重構”還要痛苦的就是“邊做業務邊架構重構”!我們的産品形象的形容為“給飛馳的法拉利跑車換引擎”,為何這樣說呢?

首先:業務不能停,不能為了架構重構而終止業務的開發,将法拉利停下來換引擎,别人都跑遠了;

其次:業務不能出問題,不能因為架構重構導緻業務無法運作,法拉利修出問題跑不了,别人也跑遠了;

第三:要根本解決問題,而不是修修補補,不是給法拉利引擎加點油,清潔一下就可以了,而是要換上新的引擎。

 巧合的是,我加入uc後到現在已經做了3個系統的架構重構了(戲稱“救火隊長”),而且每個系統的特點都不一樣,過程中各種各樣的問題都遇到過,坑也踩過,也積累了一些經驗。接下來就給大家分享一下。

我接手的第一個系統是一個背景系統,負責管理整個阿裡遊戲的遊戲相關的資料(以下簡稱m系統),重構的主要原因是因為系統耦合了p業務獨有的資料和所有業務公用的資料,導緻可擴充性比較差。其大概架構如下:

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

舉一個最簡單的例子:資料庫中的某張表,一部分字段是所有業務公用的“遊戲資料”,一部分字段是“p業務系統”獨有的資料,開發的時候如果要改這張表,代碼和邏輯都很複雜,改起來效率很低。

針對m系統存在的問題,我們的重構目标就是将遊戲資料和業務資料拆分,解開兩者的耦合,使得兩個系統都能夠獨立快速發展。

重構的方案如下:

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

重構後的效果非常明顯,重構後的m系統和p業務背景系統每月上線版本數是重構前的4倍!

 我接手的第二個系統,是負責遊戲接入的核心系統(以下簡稱s系統)。s系統是遊戲接入的核心系統,一旦s系統故障,大量遊戲玩家就不能登入遊戲,而s系統并不具備多中心的能力,一旦主機房當機,整個s系統業務就不可用了。其大概架構如下,可以看出資料庫主庫是全局單點,一旦資料庫主庫不可用,兩個叢集的寫業務都不可用了:

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

針對s系統存在的問題,我們的重構目标就是實作雙中心,使得任意一個機房都能夠提供完整的服務,在某個機房故障的時候,另外一個機房能夠全部接管所有業務。

重構方案如下:

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

重構後系統的可用性從3個9提升到4個9,重構前最誇張的一個月有4次較大的線上故障,重構後雖然也經曆了機房交換機當機、營運商線路故障、機櫃斷電等問題,但對業務都沒有什麼大的影響。

 我接手的第三個業務系統,是屬于創新業務(以下簡稱x業務)。由于是創新業務,之前的業務快速嘗試和快速發展期間,怎麼友善怎麼操作,怎麼快速怎麼做,系統設計并未投入太多精力和時間,很多東西都塞到同一個系統中,導緻到了現在已經改不動了,做一個新功能或者新業務,需要花費大量的時間來讨論和梳理各種業務邏輯,一不小心就踩個大坑。x系統的架構如下:

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

x系統的問題看起來和m系統比較類似,都是可擴充性存在問題,但其實根本原因不一樣:m系統是因為耦合了不同業務的資料導緻系統可擴充性不足,而x系統是因為将業務相關的所有功能都放在同一個系統中,導緻系統可擴充性不足;同時,所有功能都在一個系統中,也可能導緻一個功能出問題,導緻整站不可用。比如說某個功能把資料庫拖慢了,整站所有業務跟着都慢了。

針對x系統存在的問題,我們的重構目标是将各個功能拆分到不同的子系統中去,降低單個系統的複雜度。重構後的架構如下(僅僅是示例,實際架構遠比下圖複雜):

給飛馳的法拉利換引擎 - 談邊做業務邊做架構重構(1)

重構後各個系統之間通過接口互動,雖然看似增加了接口的工作量,但整體來說,各系統的發展和開發速度比原來快了很多,系統也相對更加簡單,也不會出現某個子系統有問題,所有業務都有問題。

 這三個系統重構的方案,現在回過頭來看,感覺是理所當然的,但實際上當時做分析和決策的時候,遠遠沒有這麼簡單。

以m系統為例,當時我們接手後遇到的問題有很多,例如:

資料經常出錯;

m系統是單機,單機當機後所有背景操作就不能進行了;

性能比較差,有的操作耗時好久;

界面比較醜,操作不人性化;

曆史上經過幾手轉接,代碼比較混亂;

業務資料和遊戲資料耦合,開發效率很低。。。。。。

從這麼多問題中識别出重構的目标,并不是一目了然的;而如果想一下全部解決所有的這些問題,人力和時間又不夠!

 是以架構重構首要的任務是從一大堆紛繁複雜的問題中識别出真正要通過架構重構來解決的問題,集中力量快速解決,而不是想着通過架構重構來解決所有的問題。否則的話,就會陷入人少事多頭緒亂的情況,團隊累死累活弄個大半年,最後發現好像什麼都做了,但每個問題都依然存在。尤其是對于剛接手一個新系統的架構師或者技術主管來說,一定要控制住“新官上任三把火”的沖動,避免攤大餅式或者運動式的重構和優化,謹記“步子大了會扯到蛋”的教訓 !

 那原來發現的那些問題怎麼辦呢?當然不能放任不管。以m系統為例,我們在重構完成後,又啟動了多個優化的項目去優化這些問題,但此時的優化主要是團隊内部完成即可,和其它團隊沒有太多關聯,優化的速度是很快的。如果沒有重構就進行優化的話,每次優化都要拉一大堆關聯業務的團隊來讨論方案,效率非常低下!