系統(tǒng)重構(gòu)的道與術(shù)(轉(zhuǎn)載)
最近參與了很多重構(gòu)項(xiàng)目,有以提高服務(wù)器資源利用率為目標(biāo)的Gateway網(wǎng)關(guān)、AMAPS等服務(wù)的重構(gòu),也有以提升架構(gòu)合理性和研發(fā)效率為目標(biāo)的共享業(yè)務(wù)服務(wù)化拆分,借此機(jī)會把相關(guān)內(nèi)容梳理一下,是分享更是自我總結(jié)和學(xué)習(xí)。準(zhǔn)備以重構(gòu)工作中容易產(chǎn)生誤區(qū)的地方或容易被忽視的重點(diǎn)來聊聊,既不重復(fù)網(wǎng)上千篇一律的各種方案資料,也對重構(gòu)工作有參考價值。
什么是“道和術(shù)”?個人簡單的理解,道就是思想,術(shù)是方法??芍^有道無術(shù),術(shù)尚可求也;有術(shù)無道,止于術(shù)。分別從重構(gòu)的基本思路和原則,以及常見重構(gòu)方案的應(yīng)用來分別講講系統(tǒng)重構(gòu)的“道與術(shù)”。
一、系統(tǒng)重構(gòu)之道
現(xiàn)在是進(jìn)行重構(gòu)的恰當(dāng)時機(jī)嗎?重構(gòu)前需要做什么準(zhǔn)備?如何保障重構(gòu)工作順利完成并達(dá)成預(yù)期目標(biāo)?從這幾個大家都關(guān)心的問題,來談?wù)勚貥?gòu)工作遵循的基本思路和原則。
從實(shí)際問題出發(fā)
“不能解決實(shí)際問題的重構(gòu)就是耍流氓 ”,從實(shí)際問題出發(fā),切勿為了重構(gòu)而重構(gòu),看似簡單的道理,但現(xiàn)實(shí)中確實(shí)存在為了重構(gòu)而發(fā)起的重構(gòu),或許是想應(yīng)用誘人的新技術(shù),或許是為了跟上流行趨勢,甚至有自己主動YY需求而發(fā)起的重構(gòu)。作為工程師我們需要謹(jǐn)記系統(tǒng)穩(wěn)定高于一切,任何重構(gòu)都存在風(fēng)險,沒有業(yè)務(wù)收益的重構(gòu)相當(dāng)于平白讓業(yè)務(wù)承擔(dān)非必要的風(fēng)險,這是一種極不負(fù)責(zé)的表現(xiàn)。
所以,發(fā)起重構(gòu)項(xiàng)目時,先想明白要解決什么實(shí)際問題,是為了提升性能?還是加強(qiáng)安全?或是為了快速的持續(xù)集成和發(fā)布?想明白再行動。
設(shè)定明確目標(biāo)
目標(biāo)是否明確很大程度上決定了事情的最終效果,重構(gòu)項(xiàng)目也是如此。在組織管理、目標(biāo)管理課程上經(jīng)常會提及目標(biāo)設(shè)定的SMART原則,同樣,重構(gòu)項(xiàng)目也要有具體的、可衡量、可執(zhí)行、可實(shí)現(xiàn)、且有時間限制的目標(biāo),可執(zhí)行、可實(shí)現(xiàn)、且有時間限制這三者好理解,重點(diǎn)講講具體可衡量,上面提到的待解決問題可不可以作為重構(gòu)項(xiàng)目的目標(biāo)嗎?答案不可以,問題就出在具體可衡量上,就拿以解決性能問題的重構(gòu)項(xiàng)目為例,目標(biāo)應(yīng)該是服務(wù)響應(yīng)RT要降多少? 或是單核QPS承載量提升多少?甚至也可以是服務(wù)器資源減少多少?這才是具體可衡量的目標(biāo)。
那有些不好量化的目標(biāo)怎么做到可衡量呢?拿提升服務(wù)高可用性為目的的重構(gòu)項(xiàng)目為例,目標(biāo)確實(shí)不好量化,針對這樣的問題可以以具體事件為衡量標(biāo)準(zhǔn),比如實(shí)現(xiàn)機(jī)房故障用戶無感知,或底層故障自動降級和恢復(fù)等 (系統(tǒng)高可用經(jīng)常使用幾個9的指標(biāo)來評定,但它是一個事后采集指標(biāo),用作指導(dǎo)中短周期項(xiàng)目目標(biāo)并不適合)。
阿里內(nèi)部經(jīng)常會提到工作抓手,而這個具體可衡量的目標(biāo)就是我們重構(gòu)工作的抓手。
設(shè)計(jì)要有度
“設(shè)計(jì)不足”和“過度設(shè)計(jì)”一樣都是設(shè)計(jì)失誤,設(shè)計(jì)不足是因?yàn)槿狈Ρ匾某橄笏季S和前瞻性思考,使得系統(tǒng)存在設(shè)計(jì)缺陷;而過度設(shè)計(jì)往往是對系統(tǒng)問題把脈不清,偏離實(shí)際需求過度追求擴(kuò)展性而引入了多余的設(shè)計(jì),過度設(shè)計(jì)的結(jié)果并不只是并沒什么用處的擴(kuò)展功能,更多時候它會帶來一些新的問題,比如增加系統(tǒng)維護(hù)和迭代的成本、增加線上問題排查難度等等。
設(shè)計(jì)要有度除了設(shè)計(jì)不足和過度設(shè)計(jì)外,還有一個成本收益的層面需要考慮,可能有些設(shè)計(jì)的引入能解決一部分問題,但它方案過于復(fù)雜,實(shí)施成本過高,這時候就需要從收益產(chǎn)出比上去權(quán)衡是否要采納。
設(shè)計(jì)不足幾乎沒有捷徑,需要不斷的學(xué)習(xí)和經(jīng)驗(yàn)積累。而過度設(shè)計(jì),需要我們在做設(shè)計(jì)方案時多想一想相關(guān)設(shè)計(jì)的必要性以及成本收益問題。
小步快走
提前做好迭代計(jì)劃是在重構(gòu)工作中容易被忽略的重要事項(xiàng),重構(gòu)方案設(shè)計(jì)之初就要考慮如何分階段實(shí)施,甚至為了達(dá)到分階段目的有時需要在設(shè)計(jì)方案上做一些妥協(xié)。如果把重構(gòu)比作建筑施工,小步快走層層分離的策略就相當(dāng)于搭建施工現(xiàn)場的腳手架,是一種把風(fēng)險控制在可接受范圍的有效手段。
舉一個實(shí)際的重構(gòu)經(jīng)歷,是一個訂單服務(wù),訂單量不大但業(yè)務(wù)種類很多(酒店、門票、火車票等等)。最終設(shè)計(jì)按訂單處理流程將系統(tǒng)劃分四個模塊:下單模塊、CP訂單同步模塊、訂單處理模塊、統(tǒng)計(jì)模塊。有同學(xué)問過訂單量不大拆多個模塊合適嗎?其實(shí)除了設(shè)計(jì)本身的考慮因素外,按訂單流程拆多個模塊很重要的原因是為了能夠分階段上線和驗(yàn)證,只有這樣風(fēng)險才真正可控 (因一些特定原因沒按業(yè)務(wù)垂直拆分,這里暫不詳表)。
所以系統(tǒng)重構(gòu)盡可能采用迭代實(shí)施方案,而且是從一開始就要考慮。
二、系統(tǒng)重構(gòu)之術(shù)
在系統(tǒng)重構(gòu)工作中,會使用一些具體的手段來解決所面對的特定問題,在術(shù)的部分聊聊重構(gòu)中經(jīng)常使用的一些方案,方案的具體內(nèi)容資料很多就不寫,我們這里重點(diǎn)聊聊相關(guān)方案應(yīng)用時要注意考慮哪些問題。
服務(wù)化
服務(wù)化在很多重構(gòu)項(xiàng)目中被提及,抽象、解耦、分治、統(tǒng)一是系統(tǒng)設(shè)計(jì)和重構(gòu)的重要思想,服務(wù)化是該思想的重要實(shí)踐,在運(yùn)用服務(wù)化設(shè)計(jì)時,需要注意哪些問題?
服務(wù)化目標(biāo)
做服務(wù)化設(shè)計(jì)或重構(gòu)工作的時候,首先要想清楚服務(wù)化帶來的價值,它也是我們做服務(wù)化工作的目標(biāo)。
需求層面:支持快速迭代
開發(fā)層面:代碼解耦,獨(dú)立開發(fā),降低維護(hù)成本
運(yùn)維層面:獨(dú)立部署,單獨(dú)擴(kuò)容,降級控制
上面提的是服務(wù)化帶來的價值,有意思的是,如果是一個不好的服務(wù)化設(shè)計(jì),上面也會是服務(wù)化帶來的問題,比如經(jīng)常有同學(xué)抱怨服務(wù)化設(shè)計(jì)比之前開發(fā)上線更麻煩了。
所以清晰的認(rèn)識服務(wù)化目標(biāo)是服務(wù)化工作的第一步,如果目標(biāo)沒有達(dá)成甚至帶來的是負(fù)面效果,就要重新審視相關(guān)設(shè)計(jì)是否合理了。
強(qiáng)調(diào)服務(wù)個體,弱通信
在參與服務(wù)化工作的時候經(jīng)常遇到同學(xué)上來就聊各種RPC框架或各種消息中間件,服務(wù)化是一種服務(wù)設(shè)計(jì)模式或者說一種設(shè)計(jì)思想。服務(wù)化工作強(qiáng)調(diào)的是服務(wù)個體設(shè)計(jì),具體的通信方式至少在開始階段不是那么重要。在不同階段盡量聚焦核心問題。
粒度選擇
服務(wù)化工作最難最依賴經(jīng)驗(yàn)的是服務(wù)粒度的選擇,如何結(jié)合系統(tǒng)實(shí)際特點(diǎn)正確定義子系統(tǒng)邊界,一方面有相關(guān)設(shè)計(jì)原則可以參照(比如單一原則、無狀態(tài)等等,網(wǎng)上資料很多),更多的還是經(jīng)驗(yàn)的積累,如果是系統(tǒng)重構(gòu)工作,建議從優(yōu)先級重要的模塊進(jìn)行提煉,粒度可大可小不好把控時,可以考慮先實(shí)施較大粒度的方案,這樣即使有問題可以進(jìn)一步優(yōu)化拆分,但如果一下子過細(xì)導(dǎo)致過度設(shè)計(jì),再想回去就比較難了。
高容錯性
前面提到服務(wù)化強(qiáng)調(diào)服務(wù)個體,而作為獨(dú)立的服務(wù)其容錯性設(shè)計(jì)應(yīng)該是要被重點(diǎn)考慮的,它也決定了整個服務(wù)體系的穩(wěn)定性。所以服務(wù)化不僅僅是把服務(wù)拆分出來,拆分后要分析各服務(wù)之間的依賴,區(qū)別強(qiáng)弱關(guān)系,進(jìn)行相關(guān)容錯設(shè)計(jì)。
緩存設(shè)計(jì)
如果說數(shù)據(jù)緩存是重構(gòu)工作中被使用最多的手段,估計(jì)不會有太大的歧義,使用數(shù)據(jù)緩存方案以下幾點(diǎn)需要特別注意。
緩存不是銀彈
涉及到性能優(yōu)化經(jīng)常會聽到“那我們加個緩存”吧,確實(shí)數(shù)據(jù)緩存對性能提升的效果立竿見影,幾乎成了很多同學(xué)在解決系統(tǒng)性能問題時條件反射式的選擇。
無論是新系統(tǒng)設(shè)計(jì)還是老系統(tǒng)重構(gòu),在面對性能問題時不要總把數(shù)據(jù)緩存作為第一選擇,它會蒙蔽你的眼睛,使你無法看到其他層面的問題。記得在之前一家企業(yè)軟件公司工作時,跟著公司首席架構(gòu)師做基礎(chǔ)服務(wù)設(shè)計(jì),他有一個要求就是系統(tǒng)初期設(shè)計(jì)不能考慮任何緩存設(shè)計(jì),這讓我印象深刻。性能提升就加緩存,其實(shí)是在用戰(zhàn)術(shù)上的勤奮掩蓋戰(zhàn)略上的懶惰,解決問題時我們需要多角度多維度的全面評估,這樣才有可能系統(tǒng)性的解決問題。
雪崩和穿透
數(shù)據(jù)緩存解決了數(shù)據(jù)讀取性能問題,但同時也在系統(tǒng)架構(gòu)里引入了新的故障點(diǎn)。
雪崩和穿透是引入數(shù)據(jù)緩存時需要考慮的問題。首先從業(yè)務(wù)層面要考慮相關(guān)情況下的降級策略和具體降級方案,從技術(shù)層面,緩存自身的高可用、緩存數(shù)據(jù)是否持久化、是否加入緩存預(yù)熱機(jī)制、expire time否要進(jìn)行離散設(shè)計(jì)等等這些細(xì)節(jié)都是要考慮的。
系統(tǒng)內(nèi)部優(yōu)化
代碼重構(gòu)
代碼優(yōu)化分為代碼結(jié)構(gòu)優(yōu)化和代碼內(nèi)容優(yōu)化,后者重點(diǎn)在于如何識別代碼中的bad smell,有很多具體指導(dǎo)方法,這里就不提了。而前者更多的是對代碼設(shè)計(jì)的調(diào)整,考驗(yàn)的是設(shè)計(jì)抽象能力,需要有較好的領(lǐng)域模型(DDD)知識。所以說一個好的程序員,他/她一定是個領(lǐng)域?qū)<摇?/p>
異步化改造
對于IO密集型的應(yīng)用,異步化改造是很有效的手段,但實(shí)施起困難還是挺大的,體現(xiàn)在兩方面,一是要有完整技術(shù)解決方案的支持;幸運(yùn)的是已經(jīng)有同事給我們趟好了路,解決了公司常用中間件(Hsf、Tair、Metaq、Tddl、Sentinel等)異步化的問題,給大家重點(diǎn)推薦淘寶架構(gòu)升級項(xiàng)目相關(guān)信息(羨慕無比,這種規(guī)模的重構(gòu)可遇不可求),項(xiàng)目核心就是微服務(wù)化和基于響應(yīng)式編程的異步化改造,從中可見零起步做系統(tǒng)異步化改造是多大的一個工程。另一方面是團(tuán)隊(duì)自身學(xué)習(xí)成本,需要所有參與者對異步化、響應(yīng)式編程模型要有很好的認(rèn)知,這點(diǎn)也尤其重要。
分庫分表
數(shù)據(jù)量級快速增長單庫無法滿足業(yè)務(wù)需求時,分庫分表是常用的應(yīng)對方法。
如果是開發(fā)新系統(tǒng),除非業(yè)務(wù)本身依賴海量數(shù)據(jù),否則不建議在開發(fā)初期就實(shí)施分庫分表,因?yàn)檫@會在一定程度上加大系統(tǒng)設(shè)計(jì)和開發(fā)的難度。而且一開始就讓業(yè)務(wù)開發(fā)人員關(guān)切數(shù)據(jù)分庫分表,如果他經(jīng)驗(yàn)不足容易帶來額外的困惑,將原本簡單的問題處理復(fù)雜化。
關(guān)于主鍵生成策略,有不同機(jī)制供大家選擇,目前被使用和討論較多的是Snowflake,它有一個系統(tǒng)時間上的要求,另一個是Tddl的生成策略, 兼顧了性能、全局唯一、單庫遞增的核心訴求。
分庫分表后需要考慮跨庫跨表查詢的問題,首先業(yè)務(wù)上要盡可能的避免,但像訂單業(yè)務(wù)就需要針對用戶、賣家進(jìn)行不同維度的數(shù)據(jù)拆分(可考慮主庫從庫分別使用用戶、賣家作為分表鍵) 。如果是運(yùn)營管理后臺類多條件的復(fù)雜查詢,不管是不是分庫分表,單庫同樣支持不好,非海量數(shù)據(jù)可以考慮使用ES,海量數(shù)據(jù)使用ES+HBASE。
三、說說系統(tǒng)評估
最后簡單的聊下系統(tǒng)評估,從研發(fā)角度,可以從高性能、高可用、可擴(kuò)展性、可伸縮性、安全性、可運(yùn)維性這六個維度來考量,沒有一個標(biāo)尺,也不建議使用所謂的標(biāo)準(zhǔn),系統(tǒng)評估結(jié)果一定是結(jié)合業(yè)務(wù)實(shí)際情況的結(jié)論,比如高可用,一個運(yùn)營管理類平臺多實(shí)例部署可能就是良,但如果是線上交易系統(tǒng),多機(jī)房只是起步要求。
做系統(tǒng)評估時結(jié)合業(yè)務(wù)實(shí)際情況,從上述六個維度分別按 嚴(yán)重缺失、不足、滿足 三檔進(jìn)行評估,初步分析系統(tǒng)短板。另外特別需要注意的是,這些維度不是獨(dú)立存在的,在針對某一方面進(jìn)行重構(gòu)優(yōu)化時,要深入考慮對系統(tǒng)其他層面的影響。
最后想說的是做好系統(tǒng)重構(gòu)并不容易,其困難不在具體問題的解決上,它是一個系統(tǒng)性工程,如何能做到全面考量以及考慮多方面因素后選出相對最優(yōu)解,才是最大的挑戰(zhàn)。
推薦文章
2025-01-18
2024-11-28
2024-11-09
2024-10-25
2024-06-25
2024-01-04
2023-11-06
2023-10-30
2023-10-13
2023-10-10
穩(wěn)定
產(chǎn)品高可用性高并發(fā)貼心
項(xiàng)目群及時溝通專業(yè)
產(chǎn)品經(jīng)理1v1支持快速
MVP模式小步快跑承諾
我們選擇聲譽(yù)堅(jiān)持
10年專注高端品質(zhì)開發(fā)聯(lián)系我們
友情鏈接: