架構重構秘籍:第一式對癥下藥
系統(tǒng)架構是一個不斷演化的過程。雖然有時少部分架構演化可能需要徹底推倒重寫,但大多數(shù)情況下,架構演化是通過架構重構來實現(xiàn)的。相比全新的架構設計,架構重構對架構師提出了更高的要求,主要體現(xiàn)在以下幾個方面:
業(yè)務已上線
在架構重構過程中,業(yè)務已經(jīng)在線運行,這意味著重構需要在保證業(yè)務持續(xù)發(fā)展的同時完成架構調(diào)整,類似于“給飛行中的波音747換引擎”。相比之下,新架構設計在業(yè)務尚未上線時進行,即使出現(xiàn)問題對業(yè)務的影響也較小。
關聯(lián)方眾多
架構重構涉及多個業(yè)務關聯(lián)方,各方資源投入、業(yè)務發(fā)展速度和對架構問題的敏感程度各不相同。如何減少對關聯(lián)方的影響,或者協(xié)調(diào)各方共同行動,是一項挑戰(zhàn)。新架構設計在上線前對關聯(lián)方?jīng)]有影響。
舊架構的約束
架構重構必須在舊架構基礎上進行,這是一個約束,會限制架構師的技術選擇。新架構設計中,架構師的技術選擇范圍更廣。
數(shù)據(jù)轉(zhuǎn)換
即使完全推倒重來設計新架構,新架構也會受到舊架構的約束和影響,因為業(yè)務在舊架構上產(chǎn)生的數(shù)據(jù)不能重來。新架構必須考慮如何將舊架構產(chǎn)生的數(shù)據(jù)轉(zhuǎn)換過來。
綜合能力要求
架構重構對架構師的綜合能力要求很高。他們需要說服產(chǎn)品經(jīng)理暫緩或暫停業(yè)務,與其他團隊達成一致的架構重構計劃和步驟,提出讓技術團隊認可的重構方案。因此,架構師需要在業(yè)務、團隊和技術方面具備廣泛的能力。
通常情況下,當系統(tǒng)架構無法滿足業(yè)務發(fā)展時,會出現(xiàn)一系列問題。這些問題可能表現(xiàn)為系統(tǒng)響應緩慢、數(shù)據(jù)錯誤、部分用戶訪問失敗等輕微情況,嚴重時可能導致系統(tǒng)宕機、數(shù)據(jù)庫癱瘓、數(shù)據(jù)丟失,或者系統(tǒng)開發(fā)效率低下。
起初,技術團隊可能會針對具體問題進行解決,一次又一次地應對。然而,如果問題持續(xù)存在,可能長達數(shù)月甚至一年之久,團隊可能會開始懷疑系統(tǒng)架構是否存在問題。這時,就會開始討論是否需要進行架構重構。一旦確定需要重構架構,架構師將領導架構重構的分析和實施。
當架構師開始進行架構重構分析時,往往會感到如同進入了一個迷霧森林,到處都是問題,每個問題都需要解決,讓人感到無從下手。有些架構師會開始收集系統(tǒng)當前存在的問題,并匯總成一個長達100行的Excel表格。看到這樣的表格,他們會感到困惑:這么多問題,要解決完需要花費很長時間??!
然而,期望通過架構重構解決所有問題是不現(xiàn)實的。因此,架構師的首要任務是從這些問題中識別出真正需要通過架構重構來解決的問題,并集中精力快速解決這些問題。重要的是專注于解決核心問題,而不是試圖通過架構重構解決所有問題。否則,團隊可能會陷入人手不足、任務繁多、頭緒混亂的境地,花費大量時間和精力,最終發(fā)現(xiàn)雖然做了很多工作,但每個問題依然存在。
特別是對于剛接手一個新系統(tǒng)的架構師或技術主管來說,控制住沖動,避免過度重構和優(yōu)化是很重要的。要避免進行攤大餅式或運動式的重構和優(yōu)化。
我們來看幾個具體的重構案例。
1.平臺系統(tǒng)重構:解決不合理的耦合
M 系統(tǒng)是一個后臺管理系統(tǒng),負責管理所有游戲相關的數(shù)據(jù),重構的主要原因是因為系統(tǒng)耦合了 P 業(yè)務獨有的數(shù)據(jù)和所有業(yè)務公用的數(shù)據(jù),導致可擴展性比較差。其大概架構如下圖所示。
圖片
舉一個簡單的例子:數(shù)據(jù)庫中的某張表,一部分字段是所有業(yè)務公用的“游戲數(shù)據(jù)”,一部分字段是 P 業(yè)務系統(tǒng)“獨有的數(shù)據(jù)”,開發(fā)時如果要改這張表,代碼和邏輯都很復雜,改起來效率很低。
針對 M 系統(tǒng)存在的問題,重構目標就是將游戲數(shù)據(jù)和業(yè)務數(shù)據(jù)拆分,解開兩者的耦合,使得兩個系統(tǒng)都能夠獨立快速發(fā)展。重構的方案如下圖所示。
圖片
重構后的效果非常明顯,重構后的 M 系統(tǒng)和 P 業(yè)務后臺系統(tǒng)每月上線版本數(shù)是重構前的 4 倍!
2. 游戲接入系統(tǒng)重構:解決全局單點的可用性問題
系統(tǒng)是游戲接入的核心系統(tǒng),一旦發(fā)生故障,將導致大量游戲玩家無法登錄游戲。然而,S系統(tǒng)并不具備多中心的能力,一旦主機房發(fā)生故障,整個S系統(tǒng)業(yè)務將不可用。其大概架構如下圖所示,可以看出數(shù)據(jù)庫主庫是全局單點,一旦主庫不可用,兩個集群的寫業(yè)務都將不可用。
圖片
針對 S 系統(tǒng)存在的問題,重構目標就是實現(xiàn)雙中心,使得任意一個機房都能夠提供完整的服務,在某個機房故障時,另外一個機房能夠全部接管所有業(yè)務。重構方案如下圖所示。
圖片
重構后系統(tǒng)的可用性從 3 個 9 提升到 4 個 9,重構前最夸張的一個月有 4 次較大的線上故障,重構后雖然也經(jīng)歷了機房交換機宕機、運營商線路故障、機柜斷電等問題,但對業(yè)務都沒有什么大的影響。
3.X 系統(tǒng):解決大系統(tǒng)帶來的開發(fā)效率問題
X系統(tǒng)是創(chuàng)新業(yè)務的主系統(tǒng)。在業(yè)務快速嘗試和快速發(fā)展階段,系統(tǒng)設計著重于方便操作和快速開發(fā),沒有投入太多精力和時間。許多功能都被“塞”到同一個系統(tǒng)中,導致現(xiàn)在已經(jīng)難以進行改動。為了實現(xiàn)新功能或業(yè)務,需要花費大量時間來討論和梳理各種業(yè)務邏輯,存在踩坑風險。X系統(tǒng)的架構如下圖所示。
圖片
X系統(tǒng)和M系統(tǒng)在可擴展性問題上看似相似,但根本原因不同。M系統(tǒng)的可擴展性問題源于數(shù)據(jù)耦合,而X系統(tǒng)則是因為將所有業(yè)務功能集中在一個系統(tǒng)中,導致可擴展性不足。此外,所有功能集中在一個系統(tǒng)中也可能導致某個功能出現(xiàn)問題時整站不可用的情況。舉例來說,如果某個功能導致數(shù)據(jù)庫負載過高,整站的業(yè)務都會受到影響而變慢。
針對 X 系統(tǒng)存在的問題,重構目標是將各個功能拆分到不同的子系統(tǒng)中,降低單個系統(tǒng)的復雜度。重構后的架構如下圖所示(僅僅是示例,實際架構遠比下圖復雜)。
圖片
重構后,各個系統(tǒng)之間通過接口交互,雖然增加了接口的工作量,但整體上各系統(tǒng)的發(fā)展和開發(fā)速度比原來快了很多。系統(tǒng)也相對更加簡單,不會出現(xiàn)某個子系統(tǒng)有問題導致所有業(yè)務都有問題的情況。
回顧重構這三個系統(tǒng)的方案,現(xiàn)在看來似乎是理所當然的,但實際上在進行分析和決策時并不簡單。以M系統(tǒng)為例,當時接手后遇到了許多問題:
- 數(shù)據(jù)經(jīng)常出錯。
- 單機系統(tǒng)宕機后所有后臺操作不能進行。
- 性能較差,有的操作耗時較長。
- 界面丑陋,操作不人性化。
- 代碼混亂,歷史上經(jīng)過多次轉(zhuǎn)手。
- 業(yè)務數(shù)據(jù)和游戲數(shù)據(jù)耦合,開發(fā)效率低下。
從這些問題中識別出重構的目標并不容易;要解決所有問題又需要耗費大量人力和時間!因此,架構師需要透過問題表象看到問題本質(zhì),找出真正需要通過架構重構解決的核心問題,從而做到有的放矢。這對架構師的分析和判斷能力要求非常高,不能一看到問題就想到架構重構,也不能只是針對問題進行系統(tǒng)優(yōu)化。
當然,原來發(fā)現(xiàn)的那些非架構重構問題也不能放任不管。重構完成后,我們啟動了多個優(yōu)化項目來解決這些問題,但這些優(yōu)化主要由團隊內(nèi)部完成,和其他團隊關聯(lián)較少,因此優(yōu)化速度很快。如果沒有重構而是直接進行優(yōu)化,則每次優(yōu)化都需要拉一大堆關聯(lián)業(yè)務的團隊來討論方案,效率非常低下。