系統(tǒng)重構(gòu)
在架構(gòu)設(shè)計三原則中的演化原則部分绢陌,有提到了系統(tǒng)的架構(gòu)是不斷演化的注竿,少部分架構(gòu)演化可能需要推倒重來進行重寫来氧,但絕大部分的架構(gòu)演化都是通過架構(gòu)重構(gòu)來實現(xiàn)的澄港。相比全新的架構(gòu)設(shè)計來說,架構(gòu)重構(gòu)對架構(gòu)師的要求更高垂蜗,主要體現(xiàn)在:
- 業(yè)務(wù)已經(jīng)上線喘先,不能停下來
- 架構(gòu)重構(gòu)時钳吟,業(yè)務(wù)已經(jīng)上線運行了,重構(gòu)既需要盡量保證業(yè)務(wù)繼續(xù)往前發(fā)展窘拯,又要完成架構(gòu)調(diào)整
- 這就好比“給飛行中的波音 747 換引擎”
- 而如果是新設(shè)計架構(gòu)红且,業(yè)務(wù)還沒有上線坝茎,則即使做砸了對業(yè)務(wù)也不會有太大影響
- 關(guān)聯(lián)方眾多,牽一發(fā)動全身
- 架構(gòu)重構(gòu)涉及的業(yè)務(wù)關(guān)聯(lián)方很多暇番,不同關(guān)聯(lián)方的資源投入程度嗤放、業(yè)務(wù)發(fā)展速度、對架構(gòu)痛點的敏感度等有很大差異
- 如何盡量減少對關(guān)聯(lián)方的影響壁酬,或者協(xié)調(diào)關(guān)聯(lián)方統(tǒng)一行動次酌,是一項很大的挑戰(zhàn)
- 而如果是新設(shè)計架構(gòu),則在新架構(gòu)上線前舆乔,對關(guān)聯(lián)方?jīng)]有影響
- 舊架構(gòu)的約束
- 架構(gòu)重構(gòu)需要在舊的架構(gòu)基礎(chǔ)上進行岳服,這是一個很強的約束,會限制架構(gòu)師的技術(shù)選擇范圍希俩;而如果是新設(shè)計架構(gòu)吊宋,則架構(gòu)師的技術(shù)選擇余地大得多
- 即使是我們決定推倒到重來,完全拋棄舊的架構(gòu)而去設(shè)計新的架構(gòu)颜武,新架構(gòu)也會受到舊架構(gòu)的約束和影響璃搜,因為業(yè)務(wù)在舊架構(gòu)上產(chǎn)生的數(shù)據(jù)是不能推倒重來的,新架構(gòu)必須考慮如何將舊架構(gòu)產(chǎn)生的數(shù)據(jù)轉(zhuǎn)換過來
- 因此盒刚,架構(gòu)重構(gòu)對架構(gòu)師的綜合能力要求非常高腺劣,業(yè)務(wù)上要求架構(gòu)師能夠說服產(chǎn)品經(jīng)理暫緩甚至?xí)和I(yè)務(wù)來進行架構(gòu)重構(gòu);團隊上需要架構(gòu)師能夠與其他團隊達成一致的架構(gòu)重構(gòu)計劃和步驟因块;技術(shù)上需要架構(gòu)師給出讓技術(shù)團隊認可的架構(gòu)重構(gòu)方案
- 總之,架構(gòu)重構(gòu)需要架構(gòu)師既要說得動老板籍铁,也要鎮(zhèn)得住同事涡上;既要技術(shù)攻關(guān),又要協(xié)調(diào)資源拒名;既要保證業(yè)務(wù)正常發(fā)展吩愧,又要在指定時間內(nèi)完成目標……總之就是十八般武藝要樣樣精通
有的放矢
別看架構(gòu)重構(gòu)有那么多的難度,但不要被困難所嚇倒增显,架構(gòu)師正是需要在原來一團亂麻中找到線索雁佳,然后重新穿針引線,幫助業(yè)務(wù)進一步騰飛發(fā)展同云。本文基于此問題進行討論糖权,讓大家能做到有的放矢
- 通常情況下,當系統(tǒng)架構(gòu)不滿足業(yè)務(wù)的發(fā)展時炸站,其表現(xiàn)形式是系統(tǒng)不斷出現(xiàn)各種問題
- 輕微一點的如系統(tǒng)響應(yīng)慢星澳、數(shù)據(jù)錯誤、某些用戶訪問失敗等
- 嚴重的可能是宕機旱易、數(shù)據(jù)庫癱瘓禁偎、數(shù)據(jù)丟失等腿堤,或者系統(tǒng)的開發(fā)效率很低
- 開始的時候,技術(shù)團隊可能只針對具體的問題去解決如暖,解決一個算一個笆檀,但如果持續(xù)時間較長,例如持續(xù)了半年甚至一年情況都不見好轉(zhuǎn)盒至,此時可能有人想到了系統(tǒng)的架構(gòu)是否存在問題酗洒,討論是否是因為架構(gòu)原因?qū)е铝烁鞣N問題
- 一旦確定需要進行架構(gòu)重構(gòu),就會由架構(gòu)師牽頭來進行架構(gòu)重構(gòu)的分析
- 當架構(gòu)師真正開始進行架構(gòu)重構(gòu)分析時妄迁,就會發(fā)現(xiàn)自己好像進了一個迷霧森林
- 到處都是問題寝蹈,每個問題都需要解決,不知道出路在哪里登淘,感覺如果要解決所有這些問題箫老,架構(gòu)重構(gòu)其實也無能為力
- 有的架構(gòu)師一上來搜集了系統(tǒng)當前存在的問題,然后匯總成一個 100 行的 Excel 表格黔州,看到這樣一個表格就懵了:這么多問題耍鬓,要到猴年馬月才能全部解決完啊流妻?
- 期望通過架構(gòu)重構(gòu)來解決所有問題當然是不現(xiàn)實的牲蜀,所以架構(gòu)師的首要任務(wù)是從一大堆紛繁復(fù)雜的問題中識別出真正要通過架構(gòu)重構(gòu)來解決的問題,集中力量快速解決绅这,而不是想著通過架構(gòu)重構(gòu)來解決所有的問題
- 否則就會陷入人少事多頭緒亂的處境涣达,團隊累死累活弄個大半年,最后發(fā)現(xiàn)好像什么都做了证薇,但每個問題都依然存在
- 尤其是對于剛接手一個新系統(tǒng)的架構(gòu)師或者技術(shù)主管來說度苔,一定要控制住“新官上任三把火”的沖動,避免攤大餅式或者運動式的重構(gòu)和優(yōu)化
- 下面來看幾個具體的重構(gòu)案例:
- 后臺系統(tǒng)重構(gòu):解決不合理的耦合
- M 系統(tǒng)是一個后臺管理系統(tǒng)浑度,負責管理所有游戲相關(guān)的數(shù)據(jù)寇窑,重構(gòu)的主要原因是因為系統(tǒng)耦合了 P 業(yè)務(wù)獨有的數(shù)據(jù)和所有業(yè)務(wù)公用的數(shù)據(jù),導(dǎo)致可擴展性比較差
M系統(tǒng)架構(gòu)圖
- 舉一個簡單的例子:數(shù)據(jù)庫中的某張表箩张,一部分字段是所有業(yè)務(wù)公用的“游戲數(shù)據(jù)”甩骏,一部分字段是 P 業(yè)務(wù)系統(tǒng)“獨有的數(shù)據(jù)”,開發(fā)時如果要改這張表先慷,代碼和邏輯都很復(fù)雜饮笛,改起來效率很低
- 針對 M 系統(tǒng)存在的問題,重構(gòu)目標就是將游戲數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)拆分熟掂,解開兩者的耦合缎浇,使得兩個系統(tǒng)都能夠獨立快速發(fā)展
M系統(tǒng)重構(gòu)后架構(gòu)示意圖
- 重構(gòu)后的效果非常明顯,重構(gòu)后的 M 系統(tǒng)和 P 業(yè)務(wù)后臺系統(tǒng)每月上線版本數(shù)是重構(gòu)前的 4 倍
- 游戲接入系統(tǒng)重構(gòu):解決全局單點的可用性問題
- S 系統(tǒng)是游戲接入的核心系統(tǒng)赴肚,一旦 S 系統(tǒng)故障素跺,大量游戲玩家就不能登錄游戲二蓝。而 S 系統(tǒng)并不具備多中心的能力,一旦主機房宕機指厌,整個 S 系統(tǒng)業(yè)務(wù)就不可用了
S系統(tǒng)架構(gòu)圖
- 可以看出數(shù)據(jù)庫主庫是全局單點刊愚,一旦數(shù)據(jù)庫主庫不可用,兩個集群的寫業(yè)務(wù)都不可用了
- 針對 S 系統(tǒng)存在的問題踩验,重構(gòu)目標就是實現(xiàn)雙中心纸颜,使得任意一個機房都能夠提供完整的服務(wù)识啦,在某個機房故障時书斜,另外一個機房能夠全部接管所有業(yè)務(wù)
S系統(tǒng)重構(gòu)架構(gòu)示意圖
- 重構(gòu)后系統(tǒng)的可用性從 3 個 9 提升到 4 個 9伦连,重構(gòu)前最夸張的一個月有 4 次較大的線上故障,重構(gòu)后雖然也經(jīng)歷了機房交換機宕機袭异、運營商線路故障钠龙、機柜斷電等問題,但對業(yè)務(wù)都沒有什么大的影響
- X 系統(tǒng):解決大系統(tǒng)帶來的開發(fā)效率問題
- X 系統(tǒng)是創(chuàng)新業(yè)務(wù)的主系統(tǒng)御铃,之前在業(yè)務(wù)快速嘗試和快速發(fā)展期間碴里,怎么方便怎么操作,怎么快速怎么做上真,系統(tǒng)設(shè)計并未投入太多精力和時間咬腋,很多東西都“塞”到同一個系統(tǒng)中,導(dǎo)致到了現(xiàn)在已經(jīng)改不動了睡互。做一個新功能或者新業(yè)務(wù)根竿,需要花費大量的時間來討論和梳理各種業(yè)務(wù)邏輯,一不小心就踩個大坑
X系統(tǒng)架構(gòu)示意圖
- X 系統(tǒng)的問題看起來和 M 系統(tǒng)比較類似就珠,都是可擴展性存在問題犀填,但其實根本原因不一樣:M 系統(tǒng)是因為耦合了不同業(yè)務(wù)的數(shù)據(jù)導(dǎo)致系統(tǒng)可擴展性不足,而 X 系統(tǒng)是因為將業(yè)務(wù)相關(guān)的所有功能都放在同一個系統(tǒng)中嗓违,導(dǎo)致系統(tǒng)可擴展性不足
- 同時,所有功能都在一個系統(tǒng)中图贸,也可能導(dǎo)致一個功能出問題蹂季,整站不可用。比如說某個功能把數(shù)據(jù)庫拖慢了疏日,整站所有業(yè)務(wù)跟著都慢了
- 針對 X 系統(tǒng)存在的問題偿洁,重構(gòu)目標是將各個功能拆分到不同的子系統(tǒng)中,降低單個系統(tǒng)的復(fù)雜度沟优。重構(gòu)后的架構(gòu)如下圖所示(僅僅是示例涕滋,實際架構(gòu)遠比下圖復(fù)雜):
X系統(tǒng)重構(gòu)架構(gòu)圖
- 重構(gòu)后各個系統(tǒng)之間通過接口交互,雖然看似增加了接口的工作量挠阁,但整體來說宾肺,各系統(tǒng)的發(fā)展和開發(fā)速度比原來快了很多溯饵,系統(tǒng)也相對更加簡單,也不會出現(xiàn)某個子系統(tǒng)有問題锨用,所有業(yè)務(wù)都有問題
- 這三個系統(tǒng)重構(gòu)的方案丰刊,現(xiàn)在回過頭來看,感覺是理所當然的增拥,但實際上當時做分析和決策時啄巧,遠遠沒有這么簡單。以 M 系統(tǒng)為例掌栅,當時我們接手后遇到的問題有很多秩仆,例如:
- 數(shù)據(jù)經(jīng)常出錯。
- M 系統(tǒng)是單機猾封,單機宕機后所有后臺操作就不能進行了澄耍。
- 性能比較差,有的操作耗時好久忘衍。
- 界面比較丑逾苫,操作不人性化。
- 歷史上經(jīng)過幾手轉(zhuǎn)接枚钓,代碼比較混亂铅搓。
- 業(yè)務(wù)數(shù)據(jù)和游戲數(shù)據(jù)耦合,開發(fā)效率很低
- 從這么多問題中識別出重構(gòu)的目標搀捷,并不是一目了然的星掰;
- 而如果想一下全部解決所有這些問題,人力和時間又不夠嫩舟!
- 所以架構(gòu)師需要透過問題表象看到問題本質(zhì)氢烘,找出真正需要通過架構(gòu)重構(gòu)解決的核心問題,從而做到有的放矢家厌,既不會耗費大量的人力和時間投入播玖,又能夠解決核心問題
- 這對架構(gòu)師的分析和判斷能力要求非常高,既不能看到問題就想到要架構(gòu)重構(gòu)饭于,也不能只是針對問題進行系統(tǒng)優(yōu)化蜀踏,判斷到底是采取架構(gòu)重構(gòu)還是采取系統(tǒng)優(yōu)化,可能不同的架構(gòu)師和團隊都有不同的看法
- 這里有一個簡單的做法:假設(shè)我們現(xiàn)在需要從 0 開始設(shè)計當前系統(tǒng)掰吕,新架構(gòu)和老架構(gòu)是否類似果覆?如果差異不大,說明采取系統(tǒng)優(yōu)化即可殖熟;如果差異很大局待,那可能就要進行系統(tǒng)重構(gòu)了
- 那原來發(fā)現(xiàn)的那些非架構(gòu)重構(gòu)問題怎么辦呢?當然不能放任不管。以 M 系統(tǒng)為例钳榨,我們在重構(gòu)完成后舰罚,又啟動了多個優(yōu)化的項目去優(yōu)化這些問題,但此時的優(yōu)化主要由團隊內(nèi)部完成即可重绷,和其他團隊沒有太多關(guān)聯(lián)沸停,優(yōu)化的速度是很快的。如果沒有重構(gòu)就進行優(yōu)化昭卓,則每次優(yōu)化都要拉一大堆關(guān)聯(lián)業(yè)務(wù)的團隊來討論方案愤钾,效率非常低下
總結(jié)
本文講了架構(gòu)重構(gòu)的時候需要做到有的放矢,避免像通過架構(gòu)重構(gòu)來解決所有問題候醒,希望對你有所幫助