從單體到微服務(wù):四個(gè)現(xiàn)代化優(yōu)秀實(shí)踐
當(dāng)涉及到將單體應(yīng)用程序重構(gòu)為微服務(wù)時(shí),大多數(shù)工程團(tuán)隊(duì)不知道從哪里開始。此外,最近的一項(xiàng)調(diào)查顯示,79%的現(xiàn)代化項(xiàng)目失敗,平均花費(fèi)150萬美元和16個(gè)月的時(shí)間。
在盲目進(jìn)行現(xiàn)代化項(xiàng)目之前,必須了解技術(shù)債務(wù)積累、創(chuàng)新和所有權(quán)成本、復(fù)雜性和風(fēng)險(xiǎn)等因素。
事件風(fēng)暴練習(xí)、領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)、Strangler Fig Pattern和其他都是要遵循的有用概念,但作為架構(gòu)師或開發(fā)人員,如何將單體應(yīng)用程序重構(gòu)為微服務(wù)?
完成這項(xiàng)工作的最佳實(shí)踐有很多種,在這篇文章中,我們將探討一些具體的行動(dòng),以智能地將單體分解為微服務(wù)。
這些操作包括識(shí)別服務(wù)域、將兩個(gè)服務(wù)合并為一個(gè)服務(wù)、將服務(wù)更精確地重命名以及刪除作為微服務(wù)提取候選的服務(wù)或類。最好的部分是:我們將使用人工智能(AI)和自動(dòng)化來實(shí)現(xiàn)目標(biāo),而不是試圖手動(dòng)完成這些工作。
優(yōu)秀實(shí)踐1:自動(dòng)識(shí)別服務(wù)和域
調(diào)查表明,使用白板上的便簽手動(dòng)分析一個(gè)單體的時(shí)間太長(zhǎng),成本太高,很少成功。團(tuán)隊(duì)中的哪一位架構(gòu)師或開發(fā)人員有時(shí)間和能力手工審閱數(shù)百萬行代碼和數(shù)萬個(gè)類?大型單體應(yīng)用程序需要一種自動(dòng)化、數(shù)據(jù)驅(qū)動(dòng)的方法來識(shí)別潛在的服務(wù)邊界。
讓我們選擇一個(gè)現(xiàn)成的、真實(shí)的應(yīng)用程序作為平臺(tái),在其中探索這些最佳實(shí)踐。作為Java開發(fā)人員的教程示例,Oracle提供了一個(gè)醫(yī)療記錄(MedRec)應(yīng)用程序——也稱為Avitek醫(yī)療記錄應(yīng)用程序,它是一個(gè)使用WebLogic和Java EE的傳統(tǒng)單體。
使用vFunction,我們將啟動(dòng)一個(gè)“學(xué)習(xí)”階段,使用基于調(diào)用樹和系統(tǒng)流的動(dòng)態(tài)分析、靜態(tài)分析和機(jī)器學(xué)習(xí)來識(shí)別理想的服務(wù)域。
圖1:此服務(wù)圖顯示了為提取而標(biāo)識(shí)的單個(gè)服務(wù)
在圖1中,我們看到一個(gè)服務(wù)圖,其中服務(wù)顯示為不同大小和顏色的球體,以及連接它們的線(邊)。每個(gè)球體表示vFunction自動(dòng)識(shí)別為與特定域相關(guān)的服務(wù)。這些服務(wù)的名稱和詳細(xì)信息顯示在屏幕右側(cè)。
球體的大小表示服務(wù)中包含的類的數(shù)量。顏色表示每個(gè)服務(wù)中的類“排他性”級(jí)別,指的是僅存在于該服務(wù)中的類別的百分比,而不是跨多個(gè)服務(wù)共享的類別。
紅色代表低排他性,藍(lán)色代表中排他性和綠色代表高排他性。較高的類排他性表明服務(wù)之間的邊界更好,相互依賴性更少,代碼重復(fù)更少。綜上所述,這些特征表明,將高度獨(dú)占的服務(wù)重構(gòu)為微服務(wù)將不那么復(fù)雜。
圖2和圖3:實(shí)線和虛線表示服務(wù)之間的不同關(guān)系
這里的實(shí)線表示跨服務(wù)共享的公共資源(圖2)。常見資源包括bean、同步對(duì)象、只讀DB事務(wù)和表、讀寫DB事務(wù)和表、WebSocket、文件和嵌入式文件等。虛線表示服務(wù)之間的方法調(diào)用(圖3)。
中間的黑色球體表示仍處于單體中的類,其中包含不特定于任何特定域的類和資源,因此未被選為提取的候選對(duì)象。
通過使用自動(dòng)化和人工智能來分析和公開以前包含在單體黑匣子中的新服務(wù)邊界,你現(xiàn)在可以開始在建議的參考架構(gòu)中操作服務(wù),該架構(gòu)為基于數(shù)據(jù)驅(qū)動(dòng)分析做出更好的決策掃清了道路。
優(yōu)秀實(shí)踐2:整合功能并避免重復(fù)
當(dāng)一切都在單體中時(shí),能見度有限。如果能夠公開建議的服務(wù)邊界,你可以開始做出決策并測(cè)試設(shè)計(jì)概念,例如,識(shí)別多個(gè)服務(wù)中的重疊功能。
什么時(shí)候?qū)⒕哂蓄愃乒δ艿牟煌?wù)整合到單個(gè)微服務(wù)中才有意義?最基本的例子是,作為一名架構(gòu)師,你可能會(huì)看到將兩個(gè)看起來重疊的服務(wù)組合在一起的機(jī)會(huì),我們可以根據(jù)類名和類排他性級(jí)別來識(shí)別這些服務(wù)。
圖4:兩個(gè)類似的服務(wù)已被確定要合并
在服務(wù)圖(圖4)中,我們看到了兩個(gè)類似的聊天服務(wù),它們用白色圓圈勾勒出來:PatientChatWebSocket和PhysicanChatWebSocket。我們可以看到,Physican聊天服務(wù)(紅色)具有0%的動(dòng)態(tài)排他性,而Patient聊天服務(wù)(藍(lán)色)具有略高的排他性(33%)。
這兩個(gè)服務(wù)都沒有使用任何共享資源,這表明我們可以將這些資源合并到一個(gè)服務(wù)中,而不會(huì)因?yàn)槲覀兊牟僮鞫m纏任何東西。
圖5:確認(rèn)合并服務(wù)的決定可以通過按下按鈕立即回滾
通過合并兩個(gè)類似的服務(wù),你可以合并重復(fù)的功能,并在新合并的服務(wù)中增加類的排他性(圖5)。由于我們?cè)诒纠惺褂胿Function平臺(tái),邏輯綁定這些服務(wù)所需的一切都得到了處理——類、入口點(diǎn)和資源都得到了智能更新。
圖6:新合并的單個(gè)服務(wù)現(xiàn)在表示兩個(gè)以前的聊天服務(wù)
合并服務(wù)就像將一個(gè)服務(wù)拖放到另一個(gè)服務(wù)上一樣簡(jiǎn)單,在vFunction平臺(tái)重新計(jì)算對(duì)該操作的分析后,我們看到球體現(xiàn)在是綠色的,動(dòng)態(tài)排他性為75%(圖6)。這表明新合并的服務(wù)在類級(jí)別上互連較少,并使我們有機(jī)會(huì)以較低的復(fù)雜性提取此服務(wù)。
優(yōu)秀實(shí)踐3:為服務(wù)創(chuàng)建準(zhǔn)確和有意義的名稱
我們都知道給事物命名很難。在處理單體服務(wù)時(shí),我們實(shí)際上只能使用類名來了解發(fā)生了什么。僅憑這些信息,很難準(zhǔn)確識(shí)別哪些類和功能可能屬于特定的域。
在示例中,vFunction從圖7中屏幕右側(cè)的類名中自動(dòng)導(dǎo)出服務(wù)域名。作為架構(gòu)師,你需要能夠根據(jù)偏好和需求重命名服務(wù)。
圖7:將合并的服務(wù)更精確地重命名
現(xiàn)在讓我們回到上一節(jié)中合并的兩個(gè)聊天服務(wù)。雖然以前我們有一個(gè)用于患者和醫(yī)生聊天的服務(wù),但現(xiàn)在我們有了一個(gè)代表這兩個(gè)配置文件的單一服務(wù),因此PatientChatWebSocket的名稱不再準(zhǔn)確,可能會(huì)導(dǎo)致將來使用此服務(wù)的其他開發(fā)人員產(chǎn)生誤解。我們可以選擇一個(gè)更好的名稱,例如ChatService(圖7)。
圖8:將自動(dòng)識(shí)別的服務(wù)重命名為更有意義的服務(wù)
在圖8中,我們可以看到另一個(gè)名為JaxRSRecordFacadeBroker(+2)的服務(wù)。這里的(+2)部分表示我們有屬于多個(gè)類的入口點(diǎn)。你可能會(huì)發(fā)現(xiàn)此名稱具有不必要的描述性,因此可以簡(jiǎn)單地將其更改為RecordBroker。
通過以更準(zhǔn)確和更有意義的方式重命名服務(wù),可以確保工程團(tuán)隊(duì)能夠以直接的方式快速識(shí)別和處理未來的微服務(wù)。
優(yōu)秀實(shí)踐4:確定不應(yīng)作為單獨(dú)微服務(wù)的功能
什么品質(zhì)表明,以前包含在一個(gè)整體中的功能應(yīng)該成為一個(gè)微服務(wù)?并不是所有的東西都應(yīng)該成為一個(gè)微服務(wù),所以什么時(shí)候你想刪除一個(gè)作為分離和提取候選的服務(wù)?
你可能會(huì)決定某些服務(wù)實(shí)際上不屬于單獨(dú)的域,例如,一個(gè)只過濾消息的過濾器類。因?yàn)檫@不是任何特定服務(wù)所獨(dú)有的,所以你可以決定將來將其移動(dòng)到公共庫(kù)或其他服務(wù)。
當(dāng)刪除作為未來提取為微服務(wù)的候選功能時(shí),您決定不將此類視為接收流量的單獨(dú)入口點(diǎn)。讓我們看看AuthenticationAdministrationController服務(wù)(圖9),它是一個(gè)簡(jiǎn)單的控制器類。
圖9:刪除一個(gè)非常簡(jiǎn)單的非特定服務(wù)
在圖9中,我們可以看到所選類的紅色排他性很低,而且它是一個(gè)非常小的服務(wù),只包含一個(gè)動(dòng)態(tài)類、一個(gè)靜態(tài)類,沒有資源。你可以決定它本身不應(yīng)該是一個(gè)單獨(dú)的服務(wù),并通過將其拖放到中間的黑色球體上來刪除它(圖10)。
通過將這個(gè)類重新定位到單體,我們已經(jīng)確定這個(gè)特定的功能不滿足成為單個(gè)微服務(wù)的要求。
在本文中,我們展示了架構(gòu)師和開發(fā)人員可以遵循的一些最佳實(shí)踐,以便將單體應(yīng)用程序重構(gòu)為有界的上下文和精確的域,用于未來的微服務(wù)提取。
通過使用vFunction平臺(tái),使用人工智能和數(shù)據(jù)驅(qū)動(dòng)分析,許多繁重的起始和手動(dòng)工作已經(jīng)自動(dòng)化。這確保了架構(gòu)師和開發(fā)團(tuán)隊(duì)可以將時(shí)間集中在基于智能建議的參考架構(gòu)上,而不是在沒有適當(dāng)?shù)摹叭帧鄙舷挛牡那闆r下花費(fèi)數(shù)千小時(shí)手動(dòng)分析小塊代碼。
原文鏈接::https://thenewstack.io/monoliths-to-microservices-4-modernization-best-practices-2/?