|
編者按: 如果你的工作圍繞一個(gè)大型的,復(fù)雜的單體應(yīng)用,可能你每天開(kāi)發(fā)和部署應(yīng)用的工作都是進(jìn)展緩慢而痛苦的。微服務(wù)看起來(lái)像是一個(gè)遙不可及的天堂,幸運(yùn)的是,有方法可以幫助你逃離單體架構(gòu)的地獄。本文將會(huì)介紹如何逐步地將單體應(yīng)用改造為一系列的微服務(wù)。 作者簡(jiǎn)介: Chris Richardson是Cloudfoundry.com的創(chuàng)始人,現(xiàn)在為提供開(kāi)發(fā)和部署應(yīng)用的咨詢(xún)服務(wù)。 本文是微服務(wù)系列文章的第七篇,這個(gè)系列的文章都很精彩,第一篇介紹了微服務(wù)架構(gòu)的模式,討論了微服務(wù)架構(gòu)的優(yōu)勢(shì)和缺點(diǎn),接下來(lái)的文章討論了微服務(wù)架構(gòu)的不同方面:API Gateway,進(jìn)程間的通信,服務(wù)發(fā)現(xiàn),事件驅(qū)動(dòng)的數(shù)據(jù)管理和部署微服務(wù)。你還對(duì)哪篇 文章感興趣,小編可以翻譯:
以下為第七篇的譯文:概述將單體應(yīng)用改造為微服務(wù)實(shí)際上是應(yīng)用現(xiàn)代化的過(guò)程,這是開(kāi)發(fā)者們?cè)谶^(guò)去十年來(lái)一直在做的事情,所以已經(jīng)有一些可以復(fù)用的經(jīng)驗(yàn)。 全部重寫(xiě)是絕對(duì)不能用的策略,除非你要集中精力從頭構(gòu)建一個(gè)基于微服務(wù)的應(yīng)用。雖然聽(tīng)起來(lái)很有吸引力,但是風(fēng)險(xiǎn)很大,很有可能會(huì)失敗。就像MartinFowler所說(shuō)的: 『The only thing a Big Bang rewrite guarantees is a Big Bang!』 你應(yīng)該循序漸進(jìn)地重構(gòu)你的單體應(yīng)用。你可以逐步地構(gòu)建一個(gè)部分微服務(wù)化的應(yīng)用,然后和你的單體應(yīng)用集成起來(lái)。單體應(yīng)用的實(shí)現(xiàn)的功能會(huì)逐漸變少,最終消失或變成一個(gè)新的微服務(wù)組件。 策略1:止損 Law of Holes告訴我們,如果你正在一個(gè)洞里,就不要繼續(xù)再挖了。當(dāng)你的單體應(yīng)用已經(jīng)變得無(wú)法管理的時(shí)候,就不要再繼續(xù)擴(kuò)大它的規(guī)模了。 比如你想添加新功能,不要在單體應(yīng)用中添加代碼,而要將新的代碼放在另一個(gè)單獨(dú)的微服務(wù)中。 下圖展示了使用這種方法后的系統(tǒng)架構(gòu): 除了新服務(wù)和舊的單體應(yīng)用,還有兩個(gè)組件。一個(gè)是 請(qǐng)求路由 (request router),用來(lái)處理過(guò)來(lái)的(比如HTTP)請(qǐng)求,類(lèi)似于API網(wǎng)關(guān)。這個(gè)路由發(fā)送與新功能相應(yīng)的請(qǐng)求到新的服務(wù)上,將舊服務(wù)相關(guān)的請(qǐng)求路由到單體應(yīng)用上。 另一個(gè)組件是 膠水代碼 (glue code),用來(lái)將服務(wù)與單體應(yīng)用集成起來(lái)。一個(gè)服務(wù)很少是隔離存在的,需要訪(fǎng)問(wèn)單體應(yīng)用的數(shù)據(jù)。膠水代碼就負(fù)責(zé)這些數(shù)據(jù)集成。微服務(wù)組件可以通過(guò)它來(lái)讀寫(xiě)單體應(yīng)用中的數(shù)據(jù)。 一個(gè)服務(wù)可以通過(guò)三種方式訪(fǎng)問(wèn)單體應(yīng)用中的數(shù)據(jù):
膠水代碼有時(shí)被稱(chēng)為 防腐層(anti-corruption layer) ,可以防止擁有自己原始領(lǐng)域模型的服務(wù),被來(lái)自單體領(lǐng)域模型的概念所影響。 膠水代碼可以在兩個(gè)不同的模型間充當(dāng)翻譯官,防腐層這個(gè)詞最初出現(xiàn)在Eric Evans寫(xiě)的《Domain DrivenDesign》一書(shū)中。開(kāi)發(fā)一個(gè)防腐層不是一個(gè)小工程,但如果你想從單體地獄中走出來(lái),這是很重要的。 用輕量級(jí)的服務(wù)實(shí)現(xiàn)一個(gè)新功能,有很多好處。首先,可以防止單體應(yīng)用變得更難以管理;其次,這個(gè)應(yīng)用可以被獨(dú)立地開(kāi)發(fā),部署和擴(kuò)展。 然而,這個(gè)方法并不能解決在舊有的單體部分遇到的問(wèn)題,你還需要破壞原有的單體部分。 策略2:前后端分離縮減單體應(yīng)用的一個(gè)策略是將表現(xiàn)層從業(yè)務(wù)邏輯和數(shù)據(jù)訪(fǎng)問(wèn)層中分離出來(lái),一個(gè)典型的企業(yè)應(yīng)用至少包括三種組件:
在表現(xiàn)邏輯與業(yè)務(wù)和數(shù)據(jù)訪(fǎng)問(wèn)邏輯之間通常有著明顯的區(qū)分。業(yè)務(wù)層有一個(gè)粗粒度的API,包含一個(gè)或多個(gè)外立面組成,外立面封裝了業(yè)務(wù)邏輯組件。這個(gè)API是自然的『縫合』,所以可以將單體分割為更小的應(yīng)用,一個(gè)應(yīng)用包含了表現(xiàn)層,另一個(gè)應(yīng)用包含了業(yè)務(wù)和數(shù)據(jù)訪(fǎng)問(wèn)層。分隔后,表現(xiàn)邏輯層應(yīng)用可以遠(yuǎn)程調(diào)用業(yè)務(wù)邏輯層應(yīng)用,下圖展示了改造前后的架構(gòu): 這樣分隔單體應(yīng)用有兩個(gè)主要好處。 首先你可以獨(dú)立地開(kāi)發(fā),部署和擴(kuò)展兩個(gè)應(yīng)用, 比如對(duì)于表現(xiàn)層開(kāi)發(fā)者來(lái)說(shuō),他們可以實(shí)現(xiàn)用戶(hù)界面的快速迭代,A/B測(cè)試也很容易實(shí)現(xiàn); 其次,這樣做會(huì)向外開(kāi)放一個(gè)微服務(wù)也可以調(diào)用的遠(yuǎn)程API。 但是這個(gè)策略只是部分解決方案,很有可能會(huì)變成兩個(gè)混亂的單體應(yīng)用。需要用下面第三個(gè)策略去減少單體部分的比重。 策略3:提取服務(wù) 第三個(gè)策略的目的是將單體中的模塊,轉(zhuǎn)變?yōu)閱为?dú)的微服務(wù)。每次提取一個(gè)模塊,就改造為微服務(wù),單體部分就縮減了。一旦你轉(zhuǎn)化了足夠的模塊,最后不管單體部分是完全消失了,還是變小成了另一個(gè)微服務(wù),都不是問(wèn)題了。 優(yōu)先改造哪個(gè)模塊?一個(gè)大型的復(fù)雜的單體應(yīng)用,通常包含數(shù)十甚至上百個(gè)模塊,都可以被提取出來(lái),選擇先提取哪個(gè)是個(gè)問(wèn)題。可以從容易被提取的開(kāi)始,積累微服務(wù)的經(jīng)驗(yàn),然后提取那些能給你帶來(lái)最大好處的模塊。 通常提取那些頻繁變化的模塊很有用 ,一旦你將這個(gè)模塊提取出來(lái),就可以獨(dú)立開(kāi)發(fā)和部署它了,可以加速開(kāi)發(fā)。 另外一個(gè)就是提取那些資源需求和其它部分有很大不同的模塊。 比如將一個(gè)有內(nèi)存數(shù)據(jù)庫(kù)的模塊轉(zhuǎn)變?yōu)榉?wù),就可以把它部署在內(nèi)存很大的主機(jī)上;同樣的,提取那些實(shí)現(xiàn)復(fù)雜算法的模塊,就可以把它部署在CPU多的主機(jī)上??傊@樣做有助于你擴(kuò)展應(yīng)用。 當(dāng)決定了提取哪個(gè)模塊后,需要看下現(xiàn)有的粗粒度邊界,可以幫助你將模塊轉(zhuǎn)化為服務(wù)。比如一個(gè)只會(huì)通過(guò)異步信息和其它應(yīng)用交互的模塊,就很容易能被改造為微服務(wù)。 如何提取一個(gè)模塊?第一步是在模塊和單體之間定義一個(gè)粗粒度的接口。 由于單體和微服務(wù)的數(shù)據(jù)互相都有需求,所以它 很像一個(gè)雙向的API。但是在這個(gè)模塊和應(yīng)用的剩余部分之間,有著混亂的依賴(lài)關(guān)系和細(xì)粒度的交互模式,所以實(shí)現(xiàn)這個(gè)API還是很有挑戰(zhàn)的。通過(guò)域模型實(shí)現(xiàn)的業(yè)務(wù)邏輯,改造起來(lái)尤其困難,因?yàn)楦鱾€(gè)域模型間的關(guān)系復(fù)雜。通常需要進(jìn)行大量的代碼修改,去打破這些依賴(lài)。 一旦你實(shí)現(xiàn)了細(xì)粒度的接口,就可以將模塊改造為一個(gè)獨(dú)立的服務(wù)。要寫(xiě)代碼實(shí)現(xiàn)單體和微服務(wù)間的通信,通過(guò)使用了IPC機(jī)制的API。下圖展現(xiàn)了一個(gè)架構(gòu)在改造前,改造中和改造后的樣子:
一旦你提取了這個(gè)模塊,就可以獨(dú)立地開(kāi)發(fā),部署和擴(kuò)展它了。你甚至可以從頭重寫(xiě)這個(gè)服務(wù),將這個(gè)服務(wù)和單體結(jié)合起來(lái)的API代碼就成了防腐層,相當(dāng)于兩個(gè)域模型之間的翻譯官。每次提取一個(gè)服務(wù),都是向著微服務(wù)又進(jìn)了一步,單體的比重會(huì)逐步縮減。 總結(jié)將單體架構(gòu)改造為微服務(wù)的過(guò)程是一種應(yīng)用現(xiàn)代化的形式,不應(yīng)該從頭重寫(xiě)來(lái)實(shí)現(xiàn)。而是應(yīng)該循序漸進(jìn)地改造你的應(yīng)用成為一系列微服務(wù)。有三種策略可以應(yīng)用: 用微服務(wù)實(shí)現(xiàn)新的功能;將表現(xiàn)層組件從業(yè)務(wù)和數(shù)據(jù)訪(fǎng)問(wèn)組件中分離出來(lái);改造單體中的模塊為微服務(wù)。 隨著時(shí)間的推移,你的微服務(wù)比重會(huì)增大,你的開(kāi)發(fā)團(tuán)隊(duì)的靈活性和速度也會(huì)提高。 靈雀云 ∣ 釋放云的無(wú)限潛能
長(zhǎng)按,識(shí)別二維碼,加關(guān)注 |
|
|