微服務(wù)實(shí)踐(七):從單體式架構(gòu)遷移到微服務(wù)架構(gòu)

轉(zhuǎn)載:微服務(wù)實(shí)踐(七):從單體式架構(gòu)遷移到微服務(wù)架構(gòu)


這是用微服務(wù)開發(fā)應(yīng)用系列博客的第七篇也是最后一篇峻呛。第一篇中介紹了微服務(wù)架構(gòu)模式券腔,并且討論了微服架構(gòu)的優(yōu)缺點(diǎn)钱豁;接續(xù)文章討論了微服務(wù)架構(gòu)不同方面:使用API網(wǎng)關(guān)棉钧,進(jìn)程間通信微饥,服務(wù)發(fā)現(xiàn)逗扒,事件驅(qū)動(dòng)數(shù)據(jù)管理以及部署微服務(wù)。本篇欠橘,我們將探討將應(yīng)用從單體式架構(gòu)遷移到微服務(wù)架構(gòu)需要考慮的策略。

希望讀者通過本系列文章對微服務(wù)優(yōu)缺點(diǎn)有一個(gè)比較好的理解现恼,以及何時(shí)使用這種架構(gòu)肃续。也許微服務(wù)架構(gòu)比較適合你的應(yīng)用。也許你正在開發(fā)一個(gè)大型叉袍、復(fù)雜單體式應(yīng)用始锚,日常開發(fā)和部署經(jīng)驗(yàn)非常緩慢和痛苦,而微服務(wù)看起來是遠(yuǎn)方一個(gè)極樂世界喳逛。幸運(yùn)的是瞧捌,有可以參考的脫離苦海的策略,本篇文章中,我將描述如何逐步將單體式應(yīng)用遷移到微服務(wù)架構(gòu)姐呐。

本系列其他六篇文章列表如下:

微服務(wù)實(shí)戰(zhàn)(一):微服務(wù)架構(gòu)的優(yōu)勢與不足

微服務(wù)實(shí)戰(zhàn)(二):使用API Gateway

微服務(wù)實(shí)戰(zhàn)(三):深入微服務(wù)架構(gòu)的進(jìn)程間通信

微服務(wù)實(shí)戰(zhàn)(四):服務(wù)發(fā)現(xiàn)的可行方案以及實(shí)踐案例

微服務(wù)實(shí)踐(五):微服務(wù)的事件驅(qū)動(dòng)數(shù)據(jù)管理

微服務(wù)實(shí)踐(六):選擇微服務(wù)部署策略

遷移到微服務(wù)綜述

遷移單體式應(yīng)用到微服務(wù)架構(gòu)意味著一系列現(xiàn)代化過程殿怜,有點(diǎn)像這幾代開發(fā)者一直在做的事情,實(shí)時(shí)上曙砂,當(dāng)遷移時(shí)头谜,我們可以重用一些想法。

一個(gè)策略是:不要大規(guī)模(big bang)重寫代碼(只有當(dāng)你承擔(dān)重建一套全新基于微服務(wù)的應(yīng)用時(shí)候可以采用重寫這種方法)鸠澈。重寫代碼聽起來很不錯(cuò)柱告,但實(shí)際上充滿了風(fēng)險(xiǎn)最終可能會(huì)失敗,就如Martin Fowler所說:“the only thing a Big Bang rewrite guarantees is a Big Bang!”

相反笑陈,應(yīng)該采取逐步遷移單體式應(yīng)用的策略际度,通過逐步生成微服務(wù)新應(yīng)用,與舊的單體式應(yīng)用集成涵妥,隨著時(shí)間推移乖菱,單體式應(yīng)用在整個(gè)架構(gòu)中比例逐漸下降直到消失或者成為微服務(wù)架構(gòu)一部分。這個(gè)策略有點(diǎn)像在高速路上限速到70邁對車做維護(hù)妹笆,盡管有挑戰(zhàn)块请,但是比起重寫的風(fēng)險(xiǎn)小很多。

Martin Fowler將這種現(xiàn)代化策略成為絞殺(Strangler)應(yīng)用拳缠,名字來源于雨林中的絞殺藤(strangler vine)墩新,也叫絞殺榕(strangler fig)。絞殺藤為了爬到森林頂端都要纏繞著大叔生長窟坐,一段時(shí)間后海渊,樹死了,留下樹形藤哲鸳。這種應(yīng)用也使用同一種模式臣疑,圍繞著傳統(tǒng)應(yīng)用開發(fā)了新型微服務(wù)應(yīng)用,傳統(tǒng)應(yīng)用會(huì)漸漸退出舞臺(tái)徙菠。

我們來看看其他可行策略讯沈。

策略1——停止挖掘

Law of Holes是說當(dāng)自己進(jìn)洞就應(yīng)該停止挖掘。對于單體式應(yīng)用不可管理時(shí)這是最佳建議婿奔。換句話說缺狠,應(yīng)該停止讓單體式應(yīng)用繼續(xù)變大,也就是說當(dāng)開發(fā)新功能時(shí)不應(yīng)該為舊單體應(yīng)用添加新代碼萍摊,最佳方法應(yīng)該是將新功能開發(fā)成獨(dú)立微服務(wù)挤茄。如下圖所示:

除了新服務(wù)和傳統(tǒng)應(yīng)用,還有兩個(gè)模塊冰木,其一是請求路由器穷劈,負(fù)責(zé)處理入口(http)請求笼恰,有點(diǎn)像之前提到的API網(wǎng)關(guān)。路由器將新功能請求發(fā)送給新開發(fā)的服務(wù)歇终,而將傳統(tǒng)請求還發(fā)給單體式應(yīng)用社证。

另外一個(gè)是膠水代碼(glue code),將微服務(wù)和單體應(yīng)用集成起來练湿,微服務(wù)很少能獨(dú)立存在猴仑,經(jīng)常會(huì)訪問單體應(yīng)用的數(shù)據(jù)。膠水代碼肥哎,可能在單體應(yīng)用或者為服務(wù)或者二者兼而有之辽俗,負(fù)責(zé)數(shù)據(jù)整合。微服務(wù)通過膠水代碼從單體應(yīng)用中讀寫數(shù)據(jù)篡诽。

微服務(wù)有三種方式訪問單體應(yīng)用數(shù)據(jù):

換氣單體應(yīng)用提供的遠(yuǎn)程API

直接訪問單體應(yīng)用數(shù)據(jù)庫

自己維護(hù)一份從單體應(yīng)用中同步的數(shù)據(jù)

膠水代碼也被稱為容災(zāi)層(anti-corruption layer)崖飘,這是因?yàn)槟z水代碼保護(hù)微服務(wù)全新域模型免受傳統(tǒng)單體應(yīng)用域模型污染。膠水代碼在這兩種模型間提供翻譯功能杈女。術(shù)語anti-corruption layer第一次出現(xiàn)在Eric Evans撰寫的必讀書Domain Driven Design朱浴,隨后就被提煉為一篇白皮書。開發(fā)容災(zāi)層可能有點(diǎn)不是很重要达椰,但卻是避免單體式泥潭的必要部分翰蠢。

將新功能以輕量級微服務(wù)方式實(shí)現(xiàn)由很多優(yōu)點(diǎn),例如可以阻止單體應(yīng)用變的更加無法管理啰劲。微服務(wù)本身可以開發(fā)梁沧、部署和獨(dú)立擴(kuò)展。采用微服務(wù)架構(gòu)會(huì)給開發(fā)者帶來不同的切身感受蝇裤。

然而廷支,這方法并不解決任何單體式本身問題,為了解決單體式本身問題必須深入單體應(yīng)用做出改變栓辜。我們來看看這么做的策略恋拍。

策略2——將前端和后端分離

減小單體式應(yīng)用復(fù)雜度的策略是講表現(xiàn)層和業(yè)務(wù)邏輯、數(shù)據(jù)訪問層分開藕甩。典型的企業(yè)應(yīng)用至少有三個(gè)不同元素構(gòu)成:

表現(xiàn)層——處理HTTP請求施敢,要么響應(yīng)一個(gè)RESTAPI請求,要么是提供一個(gè)基于HTML的圖形接口狭莱。對于一個(gè)復(fù)雜用戶接口應(yīng)用悯姊,表現(xiàn)層經(jīng)常是代碼重要的部分。

業(yè)務(wù)邏輯層——完成業(yè)務(wù)邏輯的應(yīng)用核心贩毕。

數(shù)據(jù)訪問層——訪問基礎(chǔ)元素,例如數(shù)據(jù)庫和消息代理陪汽。

在表現(xiàn)層與業(yè)務(wù)數(shù)據(jù)訪問層之間有清晰的隔離活箕。業(yè)務(wù)層有由若干方面組成的粗粒度(coarse-grained)的API,內(nèi)部包含了業(yè)務(wù)邏輯元素奴拦。API是可以將單體業(yè)務(wù)分割成兩個(gè)更小應(yīng)用的天然邊界谆甜,其中一個(gè)應(yīng)用是表現(xiàn)層垃僚,另外一個(gè)是業(yè)務(wù)和數(shù)據(jù)訪問邏輯。分割后规辱,表現(xiàn)邏輯應(yīng)用遠(yuǎn)程調(diào)用業(yè)務(wù)邏輯應(yīng)用谆棺,下圖表示遷移前后架構(gòu)不同:

單體應(yīng)用這么分割有兩個(gè)好處,其一使得應(yīng)用兩部分開發(fā)罕袋、部署和擴(kuò)展各自獨(dú)立改淑,特別地,允許表現(xiàn)層開發(fā)者在用戶界面上快速選擇浴讯,進(jìn)行A/B測試朵夏;其二,使得一些遠(yuǎn)程API可以被微服務(wù)調(diào)用榆纽。

然而仰猖,這種策略只是部分的解決方案。很可能應(yīng)用的兩部分之一或者全部都是不可管理的奈籽,因此需要使用第三種策略來消除剩余的單體架構(gòu)饥侵。

策略3——抽出服務(wù)

第三種遷移策略就是從單體應(yīng)用中抽取出某些模塊成為獨(dú)立微服務(wù)。每當(dāng)抽取一個(gè)模塊變成微服務(wù)衣屏,單體應(yīng)用就變簡單一些躏升;一旦轉(zhuǎn)換足夠多的模塊,單體應(yīng)用本身已經(jīng)不成為問題了勾拉,要么消失了煮甥,要么簡單到成為一個(gè)服務(wù)。

排序那個(gè)模塊應(yīng)該被轉(zhuǎn)成微服務(wù)

一個(gè)巨大的復(fù)雜單體應(yīng)用由成十上百個(gè)模塊構(gòu)成藕赞,每個(gè)都是被抽取對象成肘。決定第一個(gè)被抽取模塊一般都是挑戰(zhàn),一般最好是從最容易抽取的模塊開始斧蜕,這會(huì)讓開發(fā)者積累足夠經(jīng)驗(yàn)双霍,這些經(jīng)驗(yàn)可以為后續(xù)模塊化工作帶來巨大好處。

轉(zhuǎn)換模塊成為微服務(wù)一般很耗費(fèi)時(shí)間批销,一般可以根據(jù)獲益程度來排序洒闸,一般從經(jīng)常變化模塊開始會(huì)獲益最大。一旦轉(zhuǎn)換一個(gè)模塊為微服務(wù)均芽,就可以將其開發(fā)部署成獨(dú)立模塊丘逸,從而加速開發(fā)進(jìn)程。

將資源消耗大戶先抽取出來也是排序標(biāo)準(zhǔn)之一掀宋。例如深纲,將內(nèi)存數(shù)據(jù)庫抽取出來成為一個(gè)微服務(wù)會(huì)非常有用仲锄,可以將其部署在大內(nèi)存主機(jī)上。同樣的湃鹊,將對計(jì)算資源很敏感的算法應(yīng)用抽取出來也是非常有益的儒喊,這種服務(wù)可以被部署在有很多CPU的主機(jī)上。通過將資源消耗模塊轉(zhuǎn)換成微服務(wù)币呵,可以使得應(yīng)用易于擴(kuò)展怀愧。

查找現(xiàn)有粗粒度邊界來決定哪個(gè)模塊應(yīng)該被抽取,也是很有益的余赢,這使得移植工作更容易和簡單芯义。例如,只與其他應(yīng)用異步同步消息的模塊就是一個(gè)明顯邊界没佑,可以很簡單容易地將其轉(zhuǎn)換為微服務(wù)毕贼。

如何抽取模塊

抽取模塊第一步就是定義好模塊和單體應(yīng)用之間粗粒度接口,由于單體應(yīng)用需要微服務(wù)的數(shù)據(jù)蛤奢,反之亦然鬼癣,因此更像是一個(gè)雙向API。因?yàn)楸仨氃谪?fù)責(zé)依賴關(guān)系和細(xì)粒度接口模式之間做好平衡啤贩,因此開發(fā)這種API很有挑戰(zhàn)性待秃,尤其對使用域模型模式的業(yè)務(wù)邏輯層來說更具有挑戰(zhàn),因此經(jīng)常需要改變代碼來解決依賴性問題痹屹,如圖所示:

一旦完成粗粒度接口章郁,也就將此模塊轉(zhuǎn)換成獨(dú)立微服務(wù)。為了實(shí)現(xiàn)志衍,必須寫代碼使得單體應(yīng)用和微服務(wù)之間通過使用進(jìn)程間通信(IPC)機(jī)制的API來交換信息暖庄。如圖所示遷移前后對比:

此例中,正在使用Y模塊的Z模塊是備選抽取模塊楼肪,其元素正在被X模塊使用培廓,遷移第一步就是定義一套粗粒度APIs,第一個(gè)接口應(yīng)該是被X模塊使用的內(nèi)部接口春叫,用于激活Z模塊肩钠;第二個(gè)接口是被Z模塊使用的外部接口,用于激活Y模塊暂殖。

遷移第二步就是將模塊轉(zhuǎn)換成獨(dú)立服務(wù)价匠。內(nèi)部和外部接口都使用基于IPC機(jī)制的代碼,一般都會(huì)將Z模塊整合成一個(gè)微服務(wù)基礎(chǔ)框架呛每,來出來割接過程中的問題踩窖,例如服務(wù)發(fā)現(xiàn)。

抽取完模塊晨横,也就可以開發(fā)毙石、部署和擴(kuò)展另外一個(gè)服務(wù)廉沮,此服務(wù)獨(dú)立于單體應(yīng)用和其它服務(wù)⌒炀兀可以從頭寫代碼實(shí)現(xiàn)服務(wù);這種情況下叁幢,將服務(wù)和單體應(yīng)用整合的API代碼成為容災(zāi)層滤灯,在兩種域模型之間進(jìn)行翻譯工作。每抽取一個(gè)服務(wù)曼玩,就朝著微服務(wù)方向前進(jìn)一步鳞骤。隨著時(shí)間推移,單體應(yīng)用將會(huì)越來越簡單黍判,用戶就可以增加更多獨(dú)立的微服務(wù)豫尽。

總結(jié)

將現(xiàn)有應(yīng)用遷移成微服務(wù)架構(gòu)的現(xiàn)代化應(yīng)用,不應(yīng)該通過從頭重寫代碼方式實(shí)現(xiàn)顷帖,相反美旧,應(yīng)該通過逐步遷移的方式。有三種策略可以考慮:將新功能以微服務(wù)方式實(shí)現(xiàn)贬墩;將表現(xiàn)層與業(yè)務(wù)數(shù)據(jù)訪問層分離榴嗅;將現(xiàn)存模塊抽取變成微服務(wù)。隨著時(shí)間推移陶舞,微服務(wù)數(shù)量會(huì)增加嗽测,開發(fā)團(tuán)隊(duì)的彈性和效率將會(huì)大大增加。

@Container容器技術(shù)大會(huì)正在火熱報(bào)名中肿孵,知名公司的Docker唠粥、Kubernetes、Mesos應(yīng)用案例停做,點(diǎn)擊下圖可查看大會(huì)具體內(nèi)容晤愧。

點(diǎn)擊左下角閱讀原文鏈接可進(jìn)入大會(huì)官網(wǎng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雅宾,一起剝皮案震驚了整個(gè)濱河市养涮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眉抬,老刑警劉巖贯吓,帶你破解...
    沈念sama閱讀 212,185評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜀变,居然都是意外死亡悄谐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評論 3 385
  • 文/潘曉璐 我一進(jìn)店門库北,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爬舰,“玉大人们陆,你說我怎么就攤上這事∏橐伲” “怎么了坪仇?”我有些...
    開封第一講書人閱讀 157,684評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長垃你。 經(jīng)常有香客問我椅文,道長,這世上最難降的妖魔是什么惜颇? 我笑而不...
    開封第一講書人閱讀 56,564評論 1 284
  • 正文 為了忘掉前任皆刺,我火速辦了婚禮,結(jié)果婚禮上凌摄,老公的妹妹穿的比我還像新娘羡蛾。我一直安慰自己,他們只是感情好锨亏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,681評論 6 386
  • 文/花漫 我一把揭開白布痴怨。 她就那樣靜靜地躺著,像睡著了一般屯伞。 火紅的嫁衣襯著肌膚如雪腿箩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,874評論 1 290
  • 那天劣摇,我揣著相機(jī)與錄音珠移,去河邊找鬼。 笑死末融,一個(gè)胖子當(dāng)著我的面吹牛钧惧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勾习,決...
    沈念sama閱讀 39,025評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼浓瞪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了巧婶?” 一聲冷哼從身側(cè)響起乾颁,我...
    開封第一講書人閱讀 37,761評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艺栈,沒想到半個(gè)月后英岭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,217評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡湿右,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,545評論 2 327
  • 正文 我和宋清朗相戀三年诅妹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,694評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吭狡,死狀恐怖尖殃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情划煮,我是刑警寧澤送丰,帶...
    沈念sama閱讀 34,351評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站般此,受9級特大地震影響蚪战,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铐懊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,988評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞎疼。 院中可真熱鬧科乎,春花似錦、人聲如沸贼急。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,778評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽太抓。三九已至空闲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間走敌,已是汗流浹背碴倾。 一陣腳步聲響...
    開封第一講書人閱讀 32,007評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掉丽,地道東北人跌榔。 一個(gè)月前我還...
    沈念sama閱讀 46,427評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像捶障,于是被迫代替她去往敵國和親僧须。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,580評論 2 349

推薦閱讀更多精彩內(nèi)容