1. 程式人生 > >微服務實踐(七):從單體式架構遷移到微服務架構

微服務實踐(七):從單體式架構遷移到微服務架構

ron title 微服務架構 需要 body ros 螞蟻金服 html 分離

微服務實戰(一):微服務架構的優勢與不足

微服務實戰(二):使用API Gateway

微服務實戰(三):深入微服務架構的進程間通信

微服務實戰(四):服務發現的可行方案以及實踐案例

微服務實踐(五):微服務的事件驅動數據管理

微服務實戰(六):選擇微服務部署策略

微服務實踐(七):從單體式架構遷移到微服務架構

微服務實踐(總)-原文

微服務實踐(七):從單體式架構遷移到微服務架構

【編者的話】這是用微服務開發應用系列博客的第七篇也是最後一篇。第一篇中介紹了微服務架構模式,並且討論了微服架構的優缺點;接續文章討論了微服務架構不同方面:使用API網關,進程間通信,服務發現,事件驅動數據管理以及部署微服務。本篇,我們將探討將應用從單體式架構遷移到微服務架構需要考慮的策略。

@Container容器技術大會將於6月4日在上海光大會展中心國際大酒店舉辦,來自Rancher、攜程、PPTV、螞蟻金服、京東、浙江移動、海爾電器、唯品會、eBay、道富銀行、麻袋理財、土豆網、阿裏百川、騰訊遊戲、數人雲、點融網、華為、輕元科技、中興通訊等公司的技術負責人將帶來實踐經驗分享,5月7日之前購票只需438元,歡迎感興趣的同學搶購。


希望讀者通過本系列文章對微服務優缺點有一個比較好的理解,以及何時使用這種架構。也許微服務架構比較適合你的應用。也許你正在開發一個大型、復雜單體式應用,日常開發和部署經驗非常緩慢和痛苦,而微服務看起來是遠方一個極樂世界。幸運的是,有可以參考的脫離苦海的策略,本篇文章中,我將描述如何逐步將單體式應用遷移到微服務架構。

本系列七篇文章列表如下:
  • 微服務實戰(一):微服務架構的優勢與不足
  • 微服務實戰(二):使用API Gateway
  • 微服務實戰(三):深入微服務架構的進程間通信
  • 微服務實戰(四):服務發現的可行方案以及實踐案例
  • 微服務實踐(五):微服務的事件驅動數據管理
  • 微服務實踐(六):選擇微服務部署策略
  • 微服務實踐(七):從單體式架構遷移到微服務架構

遷移到微服務綜述

遷移單體式應用到微服務架構意味著一系列現代化過程,有點像這幾代開發者一直在做的事情,實時上,當遷移時,我們可以重用一些想法。

一個策略是:不要大規模(big bang)重寫代碼(只有當你承擔重建一套全新基於微服務的應用時候可以采用重寫這種方法)。重寫代碼聽起來很不錯,但實際上充滿了風險最終可能會失敗,就如Martin Fowler所說:“the only thing a Big Bang rewrite guarantees is a Big Bang!”

相反,應該采取逐步遷移單體式應用的策略,通過逐步生成微服務新應用,與舊的單體式應用集成,隨著時間推移,單體式應用在整個架構中比例逐漸下降直到消失或者成為微服務架構一部分。這個策略有點像在高速路上限速到70邁對車做維護,盡管有挑戰,但是比起重寫的風險小很多。

Martin Fowler將這種現代化策略成為絞殺(Strangler)應用,名字來源於雨林中的絞殺藤(strangler vine),也叫絞殺榕(strangler fig)。絞殺藤為了爬到森林頂端都要纏繞著大叔生長,一段時間後,樹死了,留下樹形藤。這種應用也使用同一種模式,圍繞著傳統應用開發了新型微服務應用,傳統應用會漸漸退出舞臺。
技術分享圖片

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

策略1——停止挖掘

Law of Holes是說當自己進洞就應該停止挖掘。對於單體式應用不可管理時這是最佳建議。換句話說,應該停止讓單體式應用繼續變大,也就是說當開發新功能時不應該為舊單體應用添加新代碼,最佳方法應該是將新功能開發成獨立微服務。如下圖所示:
技術分享圖片
除了新服務和傳統應用,還有兩個模塊,其一是請求路由器,負責處理入口(http)請求,有點像之前提到的API網關。路由器將新功能請求發送給新開發的服務,而將傳統請求還發給單體式應用。

另外一個是膠水代碼(glue code),將微服務和單體應用集成起來,微服務很少能獨立存在,經常會訪問單體應用的數據。膠水代碼,可能在單體應用或者為服務或者二者兼而有之,負責數據整合。微服務通過膠水代碼從單體應用中讀寫數據。?

微服務有三種方式訪問單體應用數據:
  1. 換氣單體應用提供的遠程API
  2. 直接訪問單體應用數據庫
  3. 自己維護一份從單體應用中同步的數據

膠水代碼也被稱為容災層(anti-corruption layer),這是因為膠水代碼保護微服務全新域模型免受傳統單體應用域模型汙染。膠水代碼在這兩種模型間提供翻譯功能。術語anti-corruption layer第一次出現在Eric Evans撰寫的必讀書Domain Driven Design,隨後就被提煉為一篇白皮書。開發容災層可能有點不是很重要,但卻是避免單體式泥潭的必要部分。

將新功能以輕量級微服務方式實現由很多優點,例如可以阻止單體應用變的更加無法管理。微服務本身可以開發、部署和獨立擴展。采用微服務架構會給開發者帶來不同的切身感受。

然而,這方法並不解決任何單體式本身問題,為了解決單體式本身問題必須深入單體應用?做出改變。我們來看看這麽做的策略。

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

減小單體式應用復雜度的策略是講表現層和業務邏輯、數據訪問層分開。典型的企業應用至少有三個不同元素構成:
  • 表現層——處理HTTP請求,要麽響應一個RESTAPI請求,要麽是提供一個基於HTML的圖形接口。對於一個復雜用戶接口應用,表現層經常是代碼重要的部分。
  • 業務邏輯層——完成業務邏輯的應用核心?
  • 數據訪問層——訪問基礎元素,例如數據庫和消息代理?

在表現層與業務數據訪問層之間有清晰的隔離。業務層有由若幹方面組成的粗粒度(coarse-grained)的API,內部包含了業務邏輯元素。API是可以將單體業務分割成兩個更小應用的天然邊界,其中一個應用是表現層,另外一個是業務和數據訪問邏輯。分割後,表現邏輯應用遠程調用業務邏輯應用,下圖表示遷移前後架構不同:?
技術分享圖片
單體應用這麽分割有兩個好處,其一使得應用兩部分開發、部署和擴展各自獨立,特別地,允許表現層開發者在用戶界面上快速選擇,進行A/B測試;其二,使得一些遠程API可以被微服務調用。

然而,這種策略只是部分的解決方案。很可能應用的兩部分之一或者全部都是不可管理的,因此需要使用第三種策略來消除剩余的單體架構。

策略3——抽出服務

第三種遷移策略就是從單體應用中抽取出某些模塊成為獨立微服務。每當抽取一個模塊變成微服務,單體應用就變簡單一些;一旦轉換足夠多的模塊,單體應用本身已經不成為問題了,要麽消失了,要麽簡單到成為一個服務。

排序那個模塊應該被轉成微服務

一個巨大的復雜單體應用由成十上百個模塊構成,每個都是被抽取對象。決定第一個被抽取模塊一般都是挑戰,一般最好是從最容易抽取的模塊開始,這會讓開發者積累足夠經驗,這些經驗可以為後續模塊化工作帶來巨大好處。

轉換模塊成為微服務一般很耗費時間,一般可以根據獲益程度來排序,一般從經常變化模塊開始會獲益最大。一旦轉換一個模塊為微服務,就可以將其開發部署成獨立模塊,從而加速開發進程。

將資源消耗大戶先抽取出來也是排序標準之一。例如,將內存數據庫抽取出來成為一個微服務會非常有用,可以將其部署在大內存主機上。同樣的,將對計算資源很敏感的算法應用抽取出來也是非常有益的,這種服務可以被部署在有很多CPU的主機上。通過將資源消耗模塊轉換成微服務,可以使得應用易於擴展。

查找現有粗粒度邊界來決定哪個模塊應該被抽取,也是很有益的,這使得移植工作更容易和簡單。例如,只與其他應用異步同步消息的模塊就是一個明顯邊界,可以很簡單容易地將其轉換為微服務。

如何抽取模塊

抽取模塊第一步就是定義好模塊和單體應用之間粗粒度接口,由於單體應用需要微服務的數據,反之亦然,因此更像是一個雙向API。因為必須在負責依賴關系和細粒度接口模式之間做好平衡,因此開發這種API很有挑戰性,尤其對使用域模型模式的業務邏輯層來說更具有挑戰,因此經常需要改變代碼來解決依賴性問題,如圖所示:

?一旦完成粗粒度接口,也就將此模塊轉換成獨立微服務。為了實現,必須寫代碼使得單體應用和微服務之間通過使用進程間通信(IPC)機制的API來交換信息。如圖所示遷移前後對比:
技術分享圖片
此例中,正在使用Y模塊的Z模塊是備選抽取模塊,其元素正在被X模塊使用,遷移第一步就是定義一套粗粒度APIs,第一個接口應該是被X模塊使用的內部接口,用於激活Z模塊;第二個接口是被Z模塊使用的外部接口,用於激活Y模塊。

遷移第二步就是將模塊轉換成獨立服務。內部和外部接口都使用基於IPC機制的代碼,一般都會將Z模塊整合成一個微服務基礎框架,來出來割接過程中的問題,例如服務發現。

抽取完模塊,也就可以開發、部署和擴展另外一個服務,此服務獨立於單體應用和其它服務。可以從頭寫代碼實現服務;這種情況下,將服務和單體應用整合的API代碼成為容災層,在兩種域模型之間進行翻譯工作。每抽取一個服務,就朝著微服務方向前進一步。隨著時間推移,單體應用將會越來越簡單,用戶就可以增加更多獨立的微服務。

總結

將現有應用遷移成微服務架構的現代化應用,不應該通過從頭重寫代碼方式實現,相反,應該通過逐步遷移的方式。有三種策略可以考慮:將新功能以微服務方式實現;將表現層與業務數據訪問層分離;將現存模塊抽取變成微服務。隨著時間推移,微服務數量會增加,開發團隊的彈性和效率將會大大增加。

原文鏈接:Refactoring a Monolith into Microservices(翻譯:楊峰)

微服務實踐(七):從單體式架構遷移到微服務架構