如何設(shè)計(jì)可落地的重構(gòu)技術(shù)方案——理論篇
一、 寫(xiě)在前面
最近重構(gòu)項(xiàng)目比較多,寫(xiě)了好幾個(gè)系統(tǒng)重構(gòu)方案,很多朋友問(wèn),寫(xiě)重構(gòu)技術(shù)方案,有沒(méi)有什么套路或者框架,都需要做哪些調(diào)研和準(zhǔn)備工作,這篇文章就重點(diǎn)聊一聊,如何設(shè)計(jì)可落地的重構(gòu)方案。
二、重構(gòu)有沒(méi)有套路
有套路,多年重構(gòu)經(jīng)驗(yàn)表明,我重構(gòu)已經(jīng)形成了自己的一套固定模式,然后在這套模式之上,根據(jù)業(yè)務(wù)場(chǎng)景不斷的變通,可以說(shuō),重構(gòu)是經(jīng)驗(yàn)的積累。所以在設(shè)計(jì)重構(gòu)方案階段,就能夠避免一些后續(xù)的坑。當(dāng)然也不能完全避坑,因?yàn)榭傆心銢](méi)有考慮到的地方,這個(gè)時(shí)候我們要做的,就是如何把風(fēng)險(xiǎn)降到最低,這個(gè)也是重構(gòu)方案的一部分(灰度方案)。
三、什么是重構(gòu)
想必每一個(gè)技術(shù)開(kāi)發(fā)都深有感觸,很多人到一個(gè)新的團(tuán)隊(duì),都會(huì)吐槽原來(lái)的代碼寫(xiě)得亂,擴(kuò)展性難,歷史包袱重。想要重構(gòu),卻不知道如何下手;也有一些說(shuō)要重構(gòu),但是很多在我看來(lái)對(duì)于重構(gòu)沒(méi)有一個(gè)正確的認(rèn)識(shí)。
下面我說(shuō)幾點(diǎn)解釋一下:
1. 重構(gòu)不是重寫(xiě)
做過(guò)開(kāi)發(fā)的同學(xué)都知道,重寫(xiě)很簡(jiǎn)單,按照產(chǎn)品的需求,實(shí)現(xiàn)需求就好了,沒(méi)有歷史包袱。但是重構(gòu)是在原有的基礎(chǔ)上改,有很多限制性,大框架不能改,對(duì)外接口不能變,存儲(chǔ)結(jié)構(gòu)設(shè)計(jì)限制等等。
2. 不要輕易批判前人的代碼
大家要相信一點(diǎn),存在即合理,原來(lái)這么設(shè)計(jì),一定有它的原因??赡墚?dāng)初調(diào)用量不大,可能當(dāng)初業(yè)務(wù)場(chǎng)景限制,可能當(dāng)初資源限制等等,你沒(méi)有經(jīng)歷過(guò),就不能感同身受。所以不要輕易去批判, 既然直到現(xiàn)在,這個(gè)業(yè)務(wù)場(chǎng)景還在迭代,甚至要面臨重構(gòu),至少說(shuō)明該業(yè)務(wù)場(chǎng)景,甚至是商業(yè)場(chǎng)景是成功的。
3. 重構(gòu)方案先行,落地可分期進(jìn)行
有時(shí)候,我們面臨的系統(tǒng)大龐大,歷史包袱重,不知道從何處下手,或者說(shuō)做完重構(gòu)需要很長(zhǎng)的時(shí)間。即便是這樣,我們的方案也一定是設(shè)計(jì)完備的(甚至要和產(chǎn)品溝通以后可能增加的業(yè)務(wù)場(chǎng)景),不僅要考慮到如何解決現(xiàn)在的問(wèn)題,還要考慮到之后的擴(kuò)展性問(wèn)題,然后再任務(wù)拆分,分期進(jìn)行,一期做哪些,二期做哪些。另外一期重構(gòu)時(shí)間不宜過(guò)長(zhǎng),要考慮到投入產(chǎn)出比問(wèn)題。
4. 不要過(guò)度設(shè)計(jì),不要為了重構(gòu)而重構(gòu)
有時(shí)候,我們通過(guò)調(diào)整參數(shù),調(diào)優(yōu)就能解決的問(wèn)題,就不需要大動(dòng)干戈。重構(gòu)一定是在最后一環(huán),萬(wàn)不得已的情況下進(jìn)行的。例如: 1、性能瓶頸,無(wú)法擴(kuò)展,2、無(wú)法滿足現(xiàn)在的業(yè)務(wù)迭代
四、 寫(xiě)重構(gòu)技術(shù)方案需要做哪些調(diào)研
調(diào)研可以說(shuō)是寫(xiě)重構(gòu)技術(shù)方案非常重要的一個(gè)環(huán)節(jié),往往能夠避免很多不必要的坑。
1. 歷史痛點(diǎn)在哪里
我們先要通過(guò)一定手段,比如:壓測(cè),監(jiān)控等等, 先找到影響原來(lái)性能和問(wèn)題的原因是什么,痛點(diǎn)是什么。只有知道原來(lái)的痛,才能知道如何對(duì)癥下藥。
2. 調(diào)研新的技術(shù)方案
例如原來(lái)的存儲(chǔ)用的Redis,現(xiàn)在想引入Mysql,那么Mysql能不能支持現(xiàn)在的業(yè)務(wù)場(chǎng)景(可能需要通過(guò)寫(xiě)demo壓測(cè)),它又有哪些優(yōu)勢(shì)(和原來(lái)對(duì)比)。亦或者本次要引入新的組件,那么組件可能選擇性有很多,選擇哪一種比較合適需要有橫向?qū)Ρ鹊鹊取?/p>
3. 梳理業(yè)務(wù)&影響范圍
例如需要梳理出所有的對(duì)外接口,這些接口目前線上的高峰期QPS,RT,995耗時(shí)是多少,都有哪些調(diào)用方。目前系統(tǒng)相關(guān)的表是否是獨(dú)立可控的,SQL語(yǔ)句都需要匯總統(tǒng)計(jì)(這個(gè)主要是分庫(kù)分表的時(shí)候考慮,因?yàn)橐紤]到SQL拆分,分庫(kù)分表的ShardingKey 和 分庫(kù)分表之后的查詢(xún)問(wèn)題)
五、設(shè)計(jì)技術(shù)方案
- 先畫(huà)出整體架構(gòu)圖[重構(gòu)前(可選)、重構(gòu)后],再畫(huà)出核心流程圖
- 表結(jié)構(gòu)設(shè)計(jì)(分庫(kù)分表),分表情況下要根據(jù)目前線上使用場(chǎng)景對(duì)分表shardingKey做一個(gè)離散度分析。
六、設(shè)計(jì)灰度方案
技術(shù)方案明確之后,再考慮如何灰度,按流量灰度,還是城市,還是開(kāi)關(guān)控制。
七、核對(duì)方案
調(diào)研階段梳理的對(duì)外接口派上用場(chǎng)了,需要針對(duì)每一個(gè)對(duì)外接口,job腳本,consumer任務(wù)等,標(biāo)注重構(gòu)改造方案。這個(gè)過(guò)程也會(huì)發(fā)現(xiàn)一些細(xì)節(jié)上的問(wèn)題,從而完善技術(shù)方案。
八、數(shù)據(jù)校驗(yàn)方案
- 可以利用目前線上請(qǐng)求的log,流量回放的方式請(qǐng)求新接口,然后對(duì)比一下返回?cái)?shù)據(jù)是否和老的一致。
- 如果對(duì)表結(jié)構(gòu)有改造,需要對(duì)比新老數(shù)據(jù)是否一致(排除不需要對(duì)比字段)
- 灰度階段可以同時(shí)請(qǐng)求新老接口,對(duì)比返回?cái)?shù)據(jù)是否一致。
九、任務(wù)拆分
對(duì)本次改造需求進(jìn)行拆分,一期做哪些列舉出來(lái) 和 二期大概規(guī)劃。
十、技術(shù)方案評(píng)審
可以先組內(nèi)小范圍評(píng)審,先解決內(nèi)部可能存在的問(wèn)題。內(nèi)部溝通完之后,再組織跨部門(mén)技術(shù)評(píng)審會(huì)議。
十一、總結(jié)
這篇文章主要講一下寫(xiě)重構(gòu)技術(shù)方案理論篇,很多都是大家知道的一些道理,但是我想說(shuō),這其中有很多細(xì)節(jié)需要確認(rèn),還需要和產(chǎn)品,或者其他組同學(xué)溝通。方案是否可落地,除了經(jīng)驗(yàn)之外,還需要各種測(cè)試和調(diào)研。
下一篇文章將給大家講一講重構(gòu)技術(shù)方案——實(shí)戰(zhàn)篇,以我們線上真實(shí)重構(gòu)——乘客排隊(duì)系統(tǒng)重構(gòu)場(chǎng)景為例,我是如何一步步寫(xiě)重構(gòu)技術(shù)方案以及后續(xù)如何落地的。
歡迎關(guān)注"淺談架構(gòu)"公眾號(hào)、不定期分享原創(chuàng)文章。
