微服务业务体系内对复用的深度探讨
本文主要在微服務(wù)體系下重新探討復(fù)用,側(cè)重于討論不同層級的復(fù)用條件和要求,以及落地節(jié)奏。
復(fù)用是一種計(jì)算機(jī)軟件工程方法和理論。從表現(xiàn)上看,復(fù)用指對曾經(jīng)編寫過的代碼加以利用,從而支撐新的功能或業(yè)務(wù)。提高復(fù)用度,不僅可以極大的節(jié)省研發(fā)資源,而且也能為系統(tǒng)帶來更好的穩(wěn)定性和可維護(hù)性。更重要的是,它能提升項(xiàng)目質(zhì)量,帶來技術(shù)進(jìn)步,是驅(qū)動(dòng)技術(shù)團(tuán)隊(duì)實(shí)現(xiàn)技術(shù)和效能良性循環(huán)的極佳途徑。
根據(jù)維基百科,軟件復(fù)用的主要思想是,將軟件看成是由不同功能部分的組件所組成的有機(jī)體,每一個(gè)組件在設(shè)計(jì)編寫時(shí)可以被設(shè)計(jì)成完成同類工作的通用工具。這樣,如果完成各種工作的組件被創(chuàng)建起來后,編寫一特定軟件的工作就變成了將各種不同組件組織連接起來的簡單問題,這對軟件產(chǎn)品的最終質(zhì)量和維護(hù)工作都有了本質(zhì)性的改變。
從實(shí)踐上看,復(fù)用不僅是指通過拷貝或引用原有代碼來復(fù)用,而且更廣泛的是,通過復(fù)用原有設(shè)計(jì)、邏輯、框架、服務(wù)等,讓原有代碼的能力可以有效被擴(kuò)展,從而支持新功能或新業(yè)務(wù),這一擴(kuò)展也包含在微服務(wù)的體系下,某一服務(wù)支持更廣泛的業(yè)務(wù)范疇。軟件設(shè)計(jì)的經(jīng)驗(yàn)、面向?qū)ο蟮脑瓌t,都可以作為方法論來指導(dǎo)復(fù)用的實(shí)踐。
依據(jù)復(fù)用的定義,復(fù)用的程度可以從使用方的的角度被度量。此處,我們定義為復(fù)用結(jié)構(gòu)體在業(yè)務(wù)體系內(nèi)對各種場景、功能或業(yè)務(wù)范疇的支持次數(shù)。復(fù)用度提高意味著效能的提高,也意味著被復(fù)用結(jié)構(gòu)體的影響范圍擴(kuò)大,對其代碼質(zhì)量要求也會(huì)提升。
1復(fù)用的層次
復(fù)用有不同層次。我們依據(jù)可復(fù)用結(jié)構(gòu)體的復(fù)雜性,從低到高依次劃分為:代碼復(fù)用、模塊復(fù)用、服務(wù)復(fù)用、產(chǎn)品復(fù)用。可復(fù)用結(jié)構(gòu)體的復(fù)雜性是指內(nèi)部組織數(shù)量、層級、關(guān)聯(lián)程度等特性。這一層次劃分可以類比蛋白質(zhì)、細(xì)胞、器官、動(dòng)物,其內(nèi)部封裝的功能和復(fù)雜性隨層次升級而提高。不過,每一層級的界限并非十分清晰,可以相互跨越。
?代碼復(fù)用
代碼復(fù)用在此處窄化為函數(shù)、方法、或類的復(fù)用,代碼是復(fù)用的最低層次,也是服務(wù)質(zhì)量的基石。復(fù)用的代碼通常無法脫離自身服務(wù)提供獨(dú)立完整的功能,不具有模塊的規(guī)模。
代碼復(fù)用有很多成熟的經(jīng)驗(yàn)和方法,如依賴設(shè)計(jì)原則、設(shè)計(jì)模式、分層等架構(gòu)思想。比如實(shí)踐開閉原則指導(dǎo)我們應(yīng)當(dāng)在不修改原有代碼的前提下給程序擴(kuò)展功能,原有的代碼都屬于被復(fù)用代碼的范疇;依賴倒置原則可以有效指導(dǎo)我們復(fù)用頂層設(shè)計(jì)及邏輯;設(shè)計(jì)模式更是提供了一整套可操作的方法和套路,讓我們更加方便簡單地復(fù)用成功的設(shè)計(jì)模式和結(jié)構(gòu)。分層架構(gòu)思想也指導(dǎo)我們,在服務(wù)開發(fā)內(nèi)部,通過對業(yè)務(wù)的分層與模塊的正交分解后,底層的代碼應(yīng)當(dāng)具有一定的可復(fù)用性。例如,阿里的編碼規(guī)范里明確分層:Service 層,復(fù)用性較低,業(yè)務(wù)編排邏輯都得放進(jìn) service 中去做;Manager 層為通用業(yè)務(wù)處理層,是對 Service 層通用能力的下沉,如緩存方案、中間件通用處理,盡可能多的可復(fù)用業(yè)務(wù)邏輯層。
在微服務(wù)體系內(nèi),代碼層次的復(fù)用往往可以被限制在單一服務(wù)內(nèi),所以其對代碼質(zhì)量的要求可以跟隨團(tuán)隊(duì)的統(tǒng)一要求。但其對設(shè)計(jì)思想、設(shè)計(jì)能力的要求較高,應(yīng)當(dāng)成為團(tuán)隊(duì)內(nèi)部高級研發(fā)的基本功,而對于低階研發(fā),這部分能力往往缺失,可以通過設(shè)計(jì)評審等方式來避免走偏。
?模塊復(fù)用
模塊復(fù)用,也叫組件復(fù)用,模塊是基于功能劃分的單位。模塊復(fù)用比代碼復(fù)用高一層級,這是因?yàn)樗ǔ?梢蕴峁┹^為獨(dú)立的功能,模塊由代碼組成且由上層代碼關(guān)聯(lián)。
在系統(tǒng)開發(fā)中,把系統(tǒng)的各個(gè)功能模塊正交分解后,底層模塊在系統(tǒng)內(nèi)被各種場景所使用,屬于復(fù)用的范疇。同一公司或團(tuán)隊(duì)的業(yè)務(wù)體系內(nèi),業(yè)務(wù)相關(guān)性往往較大,業(yè)務(wù)相關(guān)的功能模塊,其復(fù)用范圍有一定概率突破本服務(wù)內(nèi),提供給其他服務(wù)使用,進(jìn)一步提高其復(fù)用度。
業(yè)務(wù)無關(guān)的模塊復(fù)用,通常可以為各個(gè)微服務(wù)統(tǒng)一提供 SDK,如分布式事務(wù)框架、一系列的依賴注入框架,它并不能形成獨(dú)立的系統(tǒng)。這類復(fù)用的標(biāo)志之一為較小規(guī)模的代碼,可以直接放到 Github 開源,供其他公司或者業(yè)務(wù)場景使用。
優(yōu)質(zhì)的可復(fù)用模塊,可以對單一微服務(wù)內(nèi)部提供復(fù)用,來支持服務(wù)的各種擴(kuò)展功能。也有可能脫離單一的微服務(wù),在其他微服務(wù)間提供支持,模塊一旦開發(fā)完畢,其他使用者就可以花費(fèi)很少的精力就能在自身服務(wù)中集成該模塊功能。脫離單一服務(wù)的可復(fù)用模塊,由于影響范圍的擴(kuò)大,團(tuán)隊(duì)對其對代碼和文檔的質(zhì)量要求較高,模塊復(fù)用,應(yīng)當(dāng)成為團(tuán)隊(duì)有計(jì)劃去追求的產(chǎn)物。
?服務(wù)復(fù)用
微服務(wù)體系運(yùn)維體系的強(qiáng)大便利為模塊復(fù)用創(chuàng)造了一種變體,即服務(wù)復(fù)用。在微服務(wù)體系架構(gòu)中,服務(wù)復(fù)用可以分為兩種:
-
一種是指將底層的功能模塊,直接抽離成微服務(wù),單獨(dú)提供功能,如計(jì)數(shù)服務(wù)、音頻資源服務(wù)(包含加密等)、圖片服務(wù)(包含鑒黃等)。
-
另一種是被多種場景用到的業(yè)務(wù)能力,抽離為微服務(wù)支付、訂單、會(huì)員、進(jìn)度、留言、優(yōu)惠券等這類服務(wù)的復(fù)用,此類業(yè)務(wù)能力通常也屬于底層業(yè)務(wù)能力。
在公司業(yè)務(wù)體系中,服務(wù)的復(fù)用可以非常方便的擴(kuò)展支持業(yè)務(wù)邊界,這是由于服務(wù)復(fù)用封裝度較好,通過接口與其他業(yè)務(wù)進(jìn)行交互,對接操作往往簡單方便服務(wù)復(fù)用。還有一個(gè)現(xiàn)象是,如果業(yè)務(wù)場景在不同的公司也較為廣泛存在,往往會(huì)伴隨有公司以其為主營業(yè)務(wù)生存,有專業(yè)的團(tuán)隊(duì)專注做此類產(chǎn)品,如直播消息服務(wù),有融云等公司,日志統(tǒng)計(jì)服務(wù),有友盟等公司。
服務(wù)復(fù)用和模塊復(fù)用有一定可轉(zhuǎn)換性,在對存儲(chǔ)瓶頸充分預(yù)估前提下,我們傾向于優(yōu)先考慮微服務(wù),理由如下:
-
微服務(wù)功能獨(dú)立,數(shù)據(jù)存儲(chǔ)通常獨(dú)立部署,封裝更為徹底;
-
服務(wù)復(fù)用直接依賴 HTTP 等協(xié)議進(jìn)行通信,使用方完全依賴接口對接。微服務(wù)內(nèi)部可以動(dòng)態(tài)的進(jìn)行演化升級,根據(jù)此優(yōu)勢,我們也可以將傳統(tǒng)的經(jīng)常容易變動(dòng)的 SDK 改造為微服務(wù)形式;
-
微服務(wù)可以直接對客戶端或用戶提供服務(wù),減少后端服務(wù)之間的相互對接過程,降低溝通成本及出錯(cuò)成本;
-
根據(jù)康威定律,微服務(wù)的歸屬劃分往往會(huì)更為清晰,專人負(fù)責(zé),有利于在長期的演化中團(tuán)隊(duì)對邊界的把控,避免混淆進(jìn)各種影響復(fù)用代碼。
但同時(shí)也需要注意,微服務(wù)數(shù)據(jù)存儲(chǔ)獨(dú)立,意味著存儲(chǔ)容量及性能可能成為整個(gè)系統(tǒng)的瓶頸,這需要充分預(yù)估;微服務(wù)封裝徹底,對外使用 HTTP 交互,意味著功能在業(yè)務(wù)體系內(nèi)為單點(diǎn),其發(fā)生故障后,整個(gè)系統(tǒng)可能癱瘓,要做好降級故障預(yù)案,避免成為服務(wù)體系的瓶頸。
服務(wù)復(fù)用的復(fù)用度,也容易辨識,如進(jìn)度服務(wù),支撐多少個(gè)業(yè)務(wù)功能,就可以認(rèn)為其復(fù)用度為多少。一個(gè)服務(wù)承擔(dān)的職責(zé)越多,它被復(fù)用的可能性就越小服務(wù)復(fù)用應(yīng)當(dāng)恪守單一職責(zé)原則,服務(wù)復(fù)用和模塊復(fù)用類似,對團(tuán)隊(duì)架構(gòu)師及技術(shù)負(fù)責(zé)人要求較高,特別是要求架構(gòu)師對和服務(wù)邊界劃分的能力較好,應(yīng)當(dāng)成為優(yōu)秀團(tuán)隊(duì)及優(yōu)秀架構(gòu)師追求的目標(biāo)。
?產(chǎn)品復(fù)用
產(chǎn)品是對外交付的最終成果,研發(fā)為產(chǎn)品服務(wù),產(chǎn)品復(fù)用是項(xiàng)目體系內(nèi),最大程度的復(fù)用,它需要來自產(chǎn)品團(tuán)隊(duì)或管理團(tuán)隊(duì)層面的支持。
-
低層次產(chǎn)品復(fù)用,需要產(chǎn)品團(tuán)隊(duì)從不同的產(chǎn)品形態(tài)中尋找可統(tǒng)一產(chǎn)品模塊,如 U 模塊的統(tǒng)一。
-
中等層次的產(chǎn)品復(fù)用,可以直接設(shè)計(jì)出可組裝的產(chǎn)品模塊,來對模塊進(jìn)行組裝成為不同形態(tài)的產(chǎn)品。
-
高層產(chǎn)品復(fù)用是從產(chǎn)品層面在業(yè)務(wù)體系內(nèi),對當(dāng)前或未來內(nèi)的業(yè)務(wù)功能進(jìn)行統(tǒng)一,如廣告營銷平臺、SaaS、PaaS 平臺的復(fù)用等都屬于成熟的產(chǎn)品復(fù)用的范疇。高層次產(chǎn)品復(fù)用成功,也有可能催生相應(yīng)領(lǐng)域里對應(yīng)的技術(shù)服務(wù)公司。
產(chǎn)品復(fù)用對產(chǎn)品的多樣性會(huì)有一定的限制,中低層次產(chǎn)品復(fù)用對產(chǎn)品形態(tài)要求較高。高層次產(chǎn)品復(fù)用,往往需要對需求的根源進(jìn)行分析,得出一整套有創(chuàng)造性的解決方案,它也更有可能創(chuàng)造性的從根源解決需求問題,如推動(dòng)廣告營銷平臺,可以有效避免在產(chǎn)品各處侵入開發(fā)營銷邏輯。產(chǎn)品復(fù)用往往需要產(chǎn)品團(tuán)隊(duì)的主導(dǎo)或介入,對技術(shù)團(tuán)隊(duì)而言,需要有較好的產(chǎn)品意識和創(chuàng)新意識,并具備和產(chǎn)品團(tuán)隊(duì)溝通并達(dá)成一致的領(lǐng)導(dǎo)力。
2收益
復(fù)用帶來的直接收益是溝通成本和研發(fā)成本的降低。可復(fù)用結(jié)構(gòu)節(jié)約的資源量,大致等同于可復(fù)用結(jié)構(gòu)的復(fù)用度,乘以原始設(shè)計(jì)、開發(fā)、測試人力的消耗。
更重要的是,由于復(fù)用帶來的集中維護(hù)也會(huì)大大降低維護(hù)成本,缺乏復(fù)用,會(huì)導(dǎo)致同樣的邏輯,實(shí)現(xiàn)各異,散落在業(yè)務(wù)體系隨著迭代不斷腐朽,將會(huì)對整個(gè)系統(tǒng)帶來無法維護(hù)的噩夢。
復(fù)用帶來的另一收益是穩(wěn)定。部分服務(wù)實(shí)現(xiàn)復(fù)用后,已經(jīng)基本上被歸檔,如音頻服務(wù)的復(fù)用、計(jì)數(shù)服務(wù)的復(fù)用等,都已經(jīng)展現(xiàn)出了極強(qiáng)的穩(wěn)定性。業(yè)務(wù)的多變性是永恒不變的話題,與業(yè)務(wù)變化無關(guān)的穩(wěn)定性使得團(tuán)隊(duì)可以集中力量應(yīng)對變化需求。
復(fù)用是一個(gè)好的修行場所,它會(huì)帶來團(tuán)隊(duì)、設(shè)計(jì)和認(rèn)知能力的提升。每個(gè)復(fù)用組件的實(shí)現(xiàn),需要其代碼可靠,更容易被他人理解,強(qiáng)迫團(tuán)隊(duì)對好代碼的認(rèn)知提升。可復(fù)用的結(jié)構(gòu),對測試覆蓋的要求、說明文檔的要求,都和日常代碼要求不一樣,可以有效鍛煉團(tuán)隊(duì)的每一個(gè)參與者。每個(gè)層次的復(fù)用,都有對不同能力的修煉,如代碼的復(fù)用將提升對分層設(shè)計(jì)的能力提升,服務(wù)的復(fù)用直接單一職責(zé)認(rèn)知的提升及封裝變化的認(rèn)知提升。
無論何種程度的復(fù)用,都會(huì)提高整個(gè)團(tuán)隊(duì)對軟件設(shè)計(jì)原則和高質(zhì)量代碼的認(rèn)知,這將使得團(tuán)隊(duì)走上良性循環(huán)。
3落地節(jié)奏
復(fù)用的落地節(jié)奏中,有機(jī)會(huì)性的代碼復(fù)用和有計(jì)劃的代碼復(fù)用兩種,兩者都不可偏廢。
機(jī)會(huì)性的代碼復(fù)用是指,開發(fā)團(tuán)隊(duì)在做需求或項(xiàng)目的過程中,通過自己的專業(yè)能力來判斷其要開發(fā)代碼或組件在其他業(yè)務(wù)需求中被復(fù)用的可能性,從而選擇是否進(jìn)行代碼復(fù)用方式的開發(fā),或者抽離為獨(dú)立模塊或服務(wù)。
有計(jì)劃的代碼復(fù)用,是指定期梳理業(yè)務(wù)開發(fā)團(tuán)隊(duì)從戰(zhàn)略角度為了日后的開發(fā)能夠復(fù)用代碼而進(jìn)行設(shè)計(jì)開發(fā)。這也包括對過往的存量代碼進(jìn)行盤點(diǎn),主動(dòng)進(jìn)行推動(dòng)重構(gòu)開發(fā),在重構(gòu)的過程中,對已經(jīng)明顯表現(xiàn)出可復(fù)用的結(jié)構(gòu)組織進(jìn)行復(fù)用迭代。
開發(fā)團(tuán)隊(duì)業(yè)務(wù)需求繁重,團(tuán)隊(duì)進(jìn)行復(fù)用度建設(shè)的初期,可以著力采用機(jī)會(huì)性的代碼復(fù)用,以更好的貼合業(yè)務(wù)實(shí)際需要。有計(jì)劃的代碼復(fù)用有利于降低團(tuán)隊(duì)的負(fù)債和提高迅速應(yīng)對變化的能力,需要團(tuán)隊(duì)管理者定期盤點(diǎn),避免負(fù)債拖慢效率。當(dāng)然復(fù)用也伴隨有一定的代價(jià),在業(yè)務(wù)快速迭代的過程中,如果處處著眼于未來開發(fā),也將不可避免的增加當(dāng)下成本,對其平衡的把控,是團(tuán)隊(duì)領(lǐng)導(dǎo)和架構(gòu)師需要具備的能力。復(fù)用的認(rèn)知、代碼、知識、設(shè)計(jì)、文檔等,都會(huì)形成團(tuán)隊(duì)內(nèi)部所不可或缺的有形無形資產(chǎn),有效支撐團(tuán)隊(duì)效能。
?關(guān)于作者:
奇正,曾在奧多比 、百度任高級工程師,現(xiàn)任某互聯(lián)網(wǎng)公司后端業(yè)務(wù)線 Leader,先后從事過 C++、Android、Golang 的開發(fā)工作。
總結(jié)
以上是生活随笔為你收集整理的微服务业务体系内对复用的深度探讨的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试官:kill -9 进程杀不掉,怎么
- 下一篇: 35+的互联网人都哪去了