在專欄第 8 期“架構(gòu)設(shè)計(jì)三原則”中的演化原則部分拍皮,我提到了系統(tǒng)的架構(gòu)是不斷演化的,少部分架構(gòu)演化可能需要推倒重來進(jìn)行重寫独柑,但絕大部分的架構(gòu)演化都是通過架構(gòu)重構(gòu)來實(shí)現(xiàn)的。相比全新的架構(gòu)設(shè)計(jì)來說私植,架構(gòu)重構(gòu)對架構(gòu)師的要求更高,主要體現(xiàn)在:
業(yè)務(wù)已經(jīng)上線车酣,不能停下來
架構(gòu)重構(gòu)時(shí)曲稼,業(yè)務(wù)已經(jīng)上線運(yùn)行了索绪,重構(gòu)既需要盡量保證業(yè)務(wù)繼續(xù)往前發(fā)展,又要完成架構(gòu)調(diào)整贫悄,這就好比“給飛行中的波音 747 換引擎”瑞驱;而如果是新設(shè)計(jì)架構(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)痛點(diǎn)的敏感度等有很大差異逆趋,如何盡量減少對關(guān)聯(lián)方的影響盏阶,或者協(xié)調(diào)關(guān)聯(lián)方統(tǒng)一行動,是一項(xiàng)很大的挑戰(zhàn)闻书;而如果是新設(shè)計(jì)架構(gòu)名斟,則在新架構(gòu)上線前,對關(guān)聯(lián)方?jīng)]有影響魄眉。
舊架構(gòu)的約束
架構(gòu)重構(gòu)需要在舊的架構(gòu)基礎(chǔ)上進(jìn)行砰盐,這是一個(gè)很強(qiáng)的約束,會限制架構(gòu)師的技術(shù)選擇范圍坑律;而如果是新設(shè)計(jì)架構(gòu)岩梳,則架構(gòu)師的技術(shù)選擇余地大得多。
即使是我們決定推倒到重來脾歇,完全拋棄舊的架構(gòu)而去設(shè)計(jì)新的架構(gòu)蒋腮,新架構(gòu)也會受到舊架構(gòu)的約束和影響,因?yàn)闃I(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ù)來進(jìn)行架構(gòu)重構(gòu)作彤;團(tuán)隊(duì)上需要架構(gòu)師能夠與其他團(tuán)隊(duì)達(dá)成一致的架構(gòu)重構(gòu)計(jì)劃和步驟;技術(shù)上需要架構(gòu)師給出讓技術(shù)團(tuán)隊(duì)認(rèn)可的架構(gòu)重構(gòu)方案乌逐。
總之竭讳,架構(gòu)重構(gòu)需要架構(gòu)師既要說得動老板,也要鎮(zhèn)得住同事浙踢;既要技術(shù)攻關(guān)绢慢,又要協(xié)調(diào)資源;既要保證業(yè)務(wù)正常發(fā)展洛波,又要在指定時(shí)間內(nèi)完成目標(biāo)……總之就是十八般武藝要樣樣精通胰舆。
說了那么多架構(gòu)重構(gòu)的難度骚露,千萬不要被困難所嚇倒,架構(gòu)師正是需要在原來一團(tuán)亂麻中找到線索缚窿,然后重新穿針引線棘幸,幫助業(yè)務(wù)進(jìn)一步騰飛發(fā)展。接下來我將分 3 期傳授我的架構(gòu)重構(gòu)內(nèi)功心法倦零,今天先來看第一式:有的放矢误续。
通常情況下,當(dāng)系統(tǒng)架構(gòu)不滿足業(yè)務(wù)的發(fā)展時(shí)扫茅,其表現(xiàn)形式是系統(tǒng)不斷出現(xiàn)各種問題蹋嵌,輕微一點(diǎn)的如系統(tǒng)響應(yīng)慢、數(shù)據(jù)錯(cuò)誤诞帐、某些用戶訪問失敗等欣尼,嚴(yán)重的可能是宕機(jī)、數(shù)據(jù)庫癱瘓停蕉、數(shù)據(jù)丟失等愕鼓,或者系統(tǒng)的開發(fā)效率很低。開始的時(shí)候慧起,技術(shù)團(tuán)隊(duì)可能只針對具體的問題去解決菇晃,解決一個(gè)算一個(gè),但如果持續(xù)時(shí)間較長蚓挤,例如持續(xù)了半年甚至一年情況都不見好轉(zhuǎn)磺送,此時(shí)可能有人想到了系統(tǒng)的架構(gòu)是否存在問題,討論是否是因?yàn)榧軜?gòu)原因?qū)е铝烁鞣N問題灿意。一旦確定需要進(jìn)行架構(gòu)重構(gòu)估灿,就會由架構(gòu)師牽頭來進(jìn)行架構(gòu)重構(gòu)的分析。
當(dāng)架構(gòu)師真正開始進(jìn)行架構(gòu)重構(gòu)分析時(shí)缤剧,就會發(fā)現(xiàn)自己好像進(jìn)了一個(gè)迷霧森林馅袁,到處都是問題,每個(gè)問題都需要解決荒辕,不知道出路在哪里汗销,感覺如果要解決所有這些問題,架構(gòu)重構(gòu)其實(shí)也無能為力抵窒。有的架構(gòu)師一上來搜集了系統(tǒng)當(dāng)前存在的問題弛针,然后匯總成一個(gè) 100 行的 Excel 表格,看到這樣一個(gè)表格就懵了:這么多問題李皇,要到猴年馬月才能全部解決完跋髯隆?
期望通過架構(gòu)重構(gòu)來解決所有問題當(dāng)然是不現(xiàn)實(shí)的,所以架構(gòu)師的首要任務(wù)是從一大堆紛繁復(fù)雜的問題中識別出真正要通過架構(gòu)重構(gòu)來解決的問題付材,集中力量快速解決朦拖,而不是想著通過架構(gòu)重構(gòu)來解決所有的問題。否則就會陷入人少事多頭緒亂的處境厌衔,團(tuán)隊(duì)累死累活弄個(gè)大半年,最后發(fā)現(xiàn)好像什么都做了捍岳,但每個(gè)問題都依然存在富寿。尤其是對于剛接手一個(gè)新系統(tǒng)的架構(gòu)師或者技術(shù)主管來說,一定要控制住“新官上任三把火”的沖動锣夹,避免攤大餅式或者運(yùn)動式的重構(gòu)和優(yōu)化页徐。
我們來看幾個(gè)具體的重構(gòu)案例。
1. 后臺系統(tǒng)重構(gòu):解決不合理的耦合
M 系統(tǒng)是一個(gè)后臺管理系統(tǒng)银萍,負(fù)責(zé)管理所有游戲相關(guān)的數(shù)據(jù)变勇,重構(gòu)的主要原因是因?yàn)橄到y(tǒng)耦合了 P 業(yè)務(wù)獨(dú)有的數(shù)據(jù)和所有業(yè)務(wù)公用的數(shù)據(jù),導(dǎo)致可擴(kuò)展性比較差贴唇。其大概架構(gòu)如下圖所示搀绣。
舉一個(gè)簡單的例子:數(shù)據(jù)庫中的某張表,一部分字段是所有業(yè)務(wù)公用的“游戲數(shù)據(jù)”戳气,一部分字段是 P 業(yè)務(wù)系統(tǒng)“獨(dú)有的數(shù)據(jù)”链患,開發(fā)時(shí)如果要改這張表,代碼和邏輯都很復(fù)雜瓶您,改起來效率很低麻捻。
針對 M 系統(tǒng)存在的問題,重構(gòu)目標(biāo)就是將游戲數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)拆分呀袱,解開兩者的耦合贸毕,使得兩個(gè)系統(tǒng)都能夠獨(dú)立快速發(fā)展。重構(gòu)的方案如下圖所示夜赵。
重構(gòu)后的效果非常明顯明棍,重構(gòu)后的 M 系統(tǒng)和 P 業(yè)務(wù)后臺系統(tǒng)每月上線版本數(shù)是重構(gòu)前的 4 倍!
2. 游戲接入系統(tǒng)重構(gòu):解決全局單點(diǎn)的可用性問題
S 系統(tǒng)是游戲接入的核心系統(tǒng)油吭,一旦 S 系統(tǒng)故障击蹲,大量游戲玩家就不能登錄游戲。而 S 系統(tǒng)并不具備多中心的能力婉宰,一旦主機(jī)房宕機(jī)歌豺,整個(gè) S 系統(tǒng)業(yè)務(wù)就不可用了。其大概架構(gòu)如下圖所示心包,可以看出數(shù)據(jù)庫主庫是全局單點(diǎn)类咧,一旦數(shù)據(jù)庫主庫不可用,兩個(gè)集群的寫業(yè)務(wù)都不可用了。
針對 S 系統(tǒng)存在的問題痕惋,重構(gòu)目標(biāo)就是實(shí)現(xiàn)雙中心区宇,使得任意一個(gè)機(jī)房都能夠提供完整的服務(wù),在某個(gè)機(jī)房故障時(shí)值戳,另外一個(gè)機(jī)房能夠全部接管所有業(yè)務(wù)议谷。重構(gòu)方案如下圖所示。
重構(gòu)后系統(tǒng)的可用性從 3 個(gè) 9 提升到 4 個(gè) 9堕虹,重構(gòu)前最夸張的一個(gè)月有 4 次較大的線上故障卧晓,重構(gòu)后雖然也經(jīng)歷了機(jī)房交換機(jī)宕機(jī)、運(yùn)營商線路故障赴捞、機(jī)柜斷電等問題逼裆,但對業(yè)務(wù)都沒有什么大的影響。
3.X 系統(tǒng):解決大系統(tǒng)帶來的開發(fā)效率問題
X 系統(tǒng)是創(chuàng)新業(yè)務(wù)的主系統(tǒng)赦政,之前在業(yè)務(wù)快速嘗試和快速發(fā)展期間胜宇,怎么方便怎么操作,怎么快速怎么做恢着,系統(tǒng)設(shè)計(jì)并未投入太多精力和時(shí)間桐愉,很多東西都“塞”到同一個(gè)系統(tǒng)中,導(dǎo)致到了現(xiàn)在已經(jīng)改不動了然评。做一個(gè)新功能或者新業(yè)務(wù)仅财,需要花費(fèi)大量的時(shí)間來討論和梳理各種業(yè)務(wù)邏輯,一不小心就踩個(gè)大坑碗淌。X 系統(tǒng)的架構(gòu)如下圖所示盏求。
X 系統(tǒng)的問題看起來和 M 系統(tǒng)比較類似,都是可擴(kuò)展性存在問題亿眠,但其實(shí)根本原因不一樣:M 系統(tǒng)是因?yàn)轳詈狭瞬煌瑯I(yè)務(wù)的數(shù)據(jù)導(dǎo)致系統(tǒng)可擴(kuò)展性不足碎罚,而 X 系統(tǒng)是因?yàn)閷I(yè)務(wù)相關(guān)的所有功能都放在同一個(gè)系統(tǒng)中,導(dǎo)致系統(tǒng)可擴(kuò)展性不足纳像;同時(shí)荆烈,所有功能都在一個(gè)系統(tǒng)中,也可能導(dǎo)致一個(gè)功能出問題竟趾,整站不可用憔购。比如說某個(gè)功能把數(shù)據(jù)庫拖慢了,整站所有業(yè)務(wù)跟著都慢了岔帽。
針對 X 系統(tǒng)存在的問題玫鸟,重構(gòu)目標(biāo)是將各個(gè)功能拆分到不同的子系統(tǒng)中,降低單個(gè)系統(tǒng)的復(fù)雜度犀勒。重構(gòu)后的架構(gòu)如下圖所示(僅僅是示例屎飘,實(shí)際架構(gòu)遠(yuǎn)比下圖復(fù)雜)妥曲。
重構(gòu)后各個(gè)系統(tǒng)之間通過接口交互,雖然看似增加了接口的工作量钦购,但整體來說檐盟,各系統(tǒng)的發(fā)展和開發(fā)速度比原來快了很多,系統(tǒng)也相對更加簡單押桃,也不會出現(xiàn)某個(gè)子系統(tǒng)有問題葵萎,所有業(yè)務(wù)都有問題。
這三個(gè)系統(tǒng)重構(gòu)的方案怨规,現(xiàn)在回過頭來看陌宿,感覺是理所當(dāng)然的,但實(shí)際上當(dāng)時(shí)做分析和決策時(shí)波丰,遠(yuǎn)遠(yuǎn)沒有這么簡單。以 M 系統(tǒng)為例舶得,當(dāng)時(shí)我們接手后遇到的問題有很多掰烟,例如:
數(shù)據(jù)經(jīng)常出錯(cuò)。
M 系統(tǒng)是單機(jī)沐批,單機(jī)宕機(jī)后所有后臺操作就不能進(jìn)行了纫骑。
性能比較差,有的操作耗時(shí)好久九孩。
界面比較丑先馆,操作不人性化。
歷史上經(jīng)過幾手轉(zhuǎn)接躺彬,代碼比較混亂煤墙。
業(yè)務(wù)數(shù)據(jù)和游戲數(shù)據(jù)耦合,開發(fā)效率很低宪拥。
從這么多問題中識別出重構(gòu)的目標(biāo)仿野,并不是一目了然的;而如果想一下全部解決所有這些問題她君,人力和時(shí)間又不夠脚作!所以架構(gòu)師需要透過問題表象看到問題本質(zhì),找出真正需要通過架構(gòu)重構(gòu)解決的核心問題缔刹,從而做到有的放矢球涛,既不會耗費(fèi)大量的人力和時(shí)間投入,又能夠解決核心問題校镐。這對架構(gòu)師的分析和判斷能力要求非常高亿扁,既不能看到問題就想到要架構(gòu)重構(gòu),也不能只是針對問題進(jìn)行系統(tǒng)優(yōu)化灭翔,判斷到底是采取架構(gòu)重構(gòu)還是采取系統(tǒng)優(yōu)化魏烫,可能不同的架構(gòu)師和團(tuán)隊(duì)都有不同的看法辣苏。這里分享一個(gè)簡單的做法:假設(shè)我們現(xiàn)在需要從 0 開始設(shè)計(jì)當(dāng)前系統(tǒng),新架構(gòu)和老架構(gòu)是否類似哄褒?如果差異不大稀蟋,說明采取系統(tǒng)優(yōu)化即可;如果差異很大呐赡,那可能就要進(jìn)行系統(tǒng)重構(gòu)了退客。
那原來發(fā)現(xiàn)的那些非架構(gòu)重構(gòu)問題怎么辦呢?當(dāng)然不能放任不管链嘀。以 M 系統(tǒng)為例萌狂,我們在重構(gòu)完成后,又啟動了多個(gè)優(yōu)化的項(xiàng)目去優(yōu)化這些問題怀泊,但此時(shí)的優(yōu)化主要由團(tuán)隊(duì)內(nèi)部完成即可茫藏,和其他團(tuán)隊(duì)沒有太多關(guān)聯(lián),優(yōu)化的速度是很快的霹琼。如果沒有重構(gòu)就進(jìn)行優(yōu)化务傲,則每次優(yōu)化都要拉一大堆關(guān)聯(lián)業(yè)務(wù)的團(tuán)隊(duì)來討論方案,效率非常低下枣申!
小結(jié)
今天我為你講了架構(gòu)重構(gòu)的時(shí)候需要做到有的放矢售葡,避免像通過架構(gòu)重構(gòu)來解決所有問題,希望對你有所幫助忠藤。
這就是今天的全部內(nèi)容挟伙,留一道思考題給你吧,分析一下你目前開發(fā)的系統(tǒng)模孩,你覺得需要架構(gòu)重構(gòu)嗎尖阔?原因和理由是什么?
歡迎你把答案寫到留言區(qū)瓜贾,和我一起討論诺祸。相信經(jīng)過深度思考的回答,也會讓你對知識的理解更加深刻祭芦。(編輯亂入:精彩的留言有機(jī)會獲得豐厚福利哦?瓯俊)