如今,很多企業(yè)都在進(jìn)行微服務(wù)架構(gòu)重構(gòu),問題是微服務(wù)到底是不是最佳選擇?如果選擇沒有問題,微服務(wù)在什么時(shí)候用?重構(gòu)之后的技術(shù)路線和之前是怎樣一種關(guān)系?我們應(yīng)該以什么樣的方式,把之前和之后的技術(shù)結(jié)合起來……相信,這些都是很多開發(fā)者在微服務(wù)重構(gòu)過程中,必然會(huì)遇到的問題。
在筆者看來,企業(yè)在部署架構(gòu)的時(shí)候,看似是遇到問題,解決問題, 但其實(shí)要秉承一個(gè)原則,那就是“以始為終”,在開始出發(fā)前就要知道終點(diǎn)在哪里。具體到微服務(wù)架構(gòu)重構(gòu),根本目的是要解決當(dāng)前架構(gòu)的問題,最終能讓系統(tǒng)支撐業(yè)務(wù)高質(zhì)量發(fā)展。
重構(gòu)不可避免
首先,開發(fā)者需要明確的一點(diǎn)是,重構(gòu)不可避免。不管是復(fù)雜的應(yīng)用系統(tǒng),還是任意一個(gè)App,甚至是類似于office這樣的軟件,都有自己的生命周期。在漫長的生命周期里,業(yè)務(wù)和需求都在不斷變化,最后的需求和最開始的設(shè)計(jì),已經(jīng)完全不一樣,當(dāng)系統(tǒng)現(xiàn)狀和大家的認(rèn)知有嚴(yán)重沖突的時(shí)候,不重構(gòu)系統(tǒng),軟件就難以繼續(xù)維護(hù)開發(fā)下去。另外,技術(shù)開發(fā)本身也在不斷變化,比如:在代碼層需要不斷引入新代碼,加入了很多冗余的內(nèi)容,變得僵硬、脆弱、難以維護(hù),需要開發(fā)周期越來越長,Bug越來越多,所以重構(gòu)成為必然結(jié)果。
以具體微服務(wù)實(shí)踐為例,隨著長時(shí)間、多地輾轉(zhuǎn),功能越做越大,已經(jīng)沒人了解最初的設(shè)計(jì)思路和項(xiàng)目初衷;但有一個(gè)有意思的現(xiàn)象是,大家在開發(fā)新功能的時(shí)候,都喜歡把功能放在這個(gè)微服務(wù)里,開發(fā)迭代速度逐漸變慢,Bug環(huán)比穩(wěn)中有升。換言之,隨著功能的增加,該微服務(wù)退化成了單體架構(gòu)。
雖然,我們今天都在談微服務(wù),但其實(shí)不管是單體架構(gòu)還是微服務(wù),都各有優(yōu)缺點(diǎn)。比如:單體架構(gòu)雖然不夠靈活,但好處是緊湊,你想要什么變量,直接調(diào)用對(duì)象就可以了,內(nèi)存是共享狀態(tài),使得功能開發(fā)變得簡單。既然這樣,為什么要重構(gòu)呢?答案是,業(yè)務(wù)發(fā)展是最大推動(dòng)力!當(dāng)業(yè)務(wù)方準(zhǔn)備進(jìn)行一次較大規(guī)模的新業(yè)務(wù)嘗試,新業(yè)務(wù)形式上有很大變化,不過核心業(yè)務(wù)功能變化不大,但研究團(tuán)隊(duì)發(fā)現(xiàn)服務(wù)復(fù)用很困難。
用領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)驅(qū)動(dòng)系統(tǒng)重構(gòu)
那么,我們到底以什么樣的方式去設(shè)計(jì)我們的系統(tǒng)?
當(dāng)項(xiàng)目簡單的時(shí)候,有兩種開發(fā)方式:一種是CRUD Design,增刪改查,有什么做什么;另一種DomAIn Driven Design,就是我們常說的DDD領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)。項(xiàng)目簡單的時(shí)候,CRUD開發(fā)成本更低,而DDD設(shè)計(jì)模式需要把業(yè)務(wù)領(lǐng)域分析清楚以后,做合適的服務(wù)分析,做合適的對(duì)象設(shè)計(jì),進(jìn)而通過合適的領(lǐng)域設(shè)計(jì)去完成。
值得一提的是,CRUD和DDD會(huì)有一個(gè)交叉點(diǎn),而業(yè)務(wù)最終的演進(jìn)方向一定會(huì)向復(fù)雜的方向發(fā)展。尤其是互聯(lián)網(wǎng)項(xiàng)目,開始只是做一些簡單的業(yè)務(wù)邏輯實(shí)現(xiàn),之后隨著業(yè)務(wù)的發(fā)展,會(huì)變得越來越復(fù)雜,傳統(tǒng)開發(fā)方式就會(huì)變得艱難。
所以,在使用微服務(wù)之前,一定不要指望微服務(wù)能做什么,微服務(wù)不是靈丹妙藥,也不是尚方寶劍,不能解決一切問題。
微服務(wù)重構(gòu)復(fù)盤
通過微服務(wù)進(jìn)行系統(tǒng)重構(gòu),大概需要六個(gè)步驟:
第一,把當(dāng)前系統(tǒng)設(shè)計(jì)與問題匯總討論。比如:架構(gòu)與代碼混亂,需求迭代困難,部署麻煩,Bug頻率逐漸升高等等,都匯總在一起。
第二,針對(duì)問題分析具體原因。微服務(wù)A太龐大,微服務(wù)B和C職責(zé)不清,團(tuán)隊(duì)內(nèi)業(yè)務(wù)理解不一致,內(nèi)部代碼設(shè)計(jì)不良,硬編碼和耦合太多……尋找這些問題的具體原因。
第三,重新梳理業(yè)務(wù)流程,明確業(yè)務(wù)術(shù)語,進(jìn)行DDD戰(zhàn)略設(shè)計(jì)。比如:活動(dòng)圖,子域分解,限界上下文設(shè)計(jì)等等,理解這些專業(yè)用語,用于戰(zhàn)略設(shè)計(jì)。
第四,針對(duì)當(dāng)前系統(tǒng)實(shí)現(xiàn)和DDD設(shè)計(jì)不匹配的地方設(shè)計(jì)微服務(wù)重構(gòu)方案。
第五,DDD戰(zhàn)術(shù)設(shè)計(jì)與技術(shù)驗(yàn)證,比如:聚合、實(shí)體、值對(duì)象設(shè)計(jì)、打樣代碼開發(fā)。
第六,任務(wù)分解與持續(xù)重構(gòu),在不影響業(yè)務(wù)開發(fā)的前提下,按照戰(zhàn)略與戰(zhàn)術(shù)設(shè)計(jì),將重構(gòu)開發(fā)和業(yè)務(wù)迭代有機(jī)結(jié)合。
需要重點(diǎn)強(qiáng)調(diào)的是,不管是微服務(wù),還是單體服務(wù),任何技術(shù)都一樣,都是解決特定問題的一個(gè)具體方法。而其中,微服務(wù)的正確解法是,先分析問題,再找合適的方案。大體來看,微服務(wù)的真正難點(diǎn)不是技術(shù),而是業(yè)務(wù)。技術(shù)問題解決起來非常容易,但業(yè)務(wù)問題不好梳理。企業(yè)需要先解決業(yè)務(wù)問題,重新梳理業(yè)務(wù),再找合適的工具和方法。