【轉】應用架構一團糟?如何將單體應用改造為微服務

概述

將單體應用改造為微服務實際上是應用現代化的過程,這是開發者們在過去十年來一直在做的事情,所以已經有一些可以復用的經驗。

全部重寫是絕對不能用的策略,除非你要集中精力從頭構建一個基于微服務的應用。雖然聽起來很有吸引力,但是風險很大,很有可能會失敗。就像MartinFowler所說的:?『The only thing a Big Bang rewrite guarantees is a Big Bang!』

你應該循序漸進地重構你的單體應用。你可以逐步地構建一個部分微服務化的應用,然后和你的單體應用集成起來。單體應用的實現的功能會逐漸變少,最終消失或變成一個新的微服務組件。

種應用現代化的策略為Strangler Application。這個名字來源于在熱帶雨林發現的一種植物Strangler vine,?為了夠到充足的陽光,?它們繞樹生長,一直向上。當樹木死后,只會留下一個樹形的藤蔓。應用的現代化就是類似的模式,我們會在舊有的應用上,構建一個新的包含微服務的應用,慢慢取代舊的應用。下面一起來看下這些策略:

策略1:止損

Law of Holes告訴我們,如果你正在一個洞里,就不要繼續再挖了。當你的單體應用已經變得無法管理的時候,就不要再繼續擴大它的規模了。?比如你想添加新功能,不要在單體應用中添加代碼,而要將新的代碼放在另一個單獨的微服務中。?下圖展示了使用這種方法后的系統架構:?

除了新服務和舊的單體應用,還有兩個組件。一個是?請求路由?(request router),用來處理過來的(比如HTTP)請求,類似于API網關。這個路由發送與新功能相應的請求到新的服務上,將舊服務相關的請求路由到單體應用上。

另一個組件是?膠水代碼?(glue code),用來將服務與單體應用集成起來。一個服務很少是隔離存在的,需要訪問單體應用的數據。膠水代碼就負責這些數據集成。微服務組件可以通過它來讀寫單體應用中的數據。

一個服務可以通過三種方式訪問單體應用中的數據:

  • 通過調用單體應用提供的遠程API

  • 直接訪問單體的數據庫

  • 保存一份數據的副本,和單體數據庫保持同步

膠水代碼有時被稱為?防腐層(anti-corruption layer)?,可以防止擁有自己原始領域模型的服務,被來自單體領域模型的概念所影響。

膠水代碼可以在兩個不同的模型間充當翻譯官,防腐層這個詞最初出現在Eric Evans寫的《Domain DrivenDesign》一書中。開發一個防腐層不是一個小工程,但如果你想從單體地獄中走出來,這是很重要的。

用輕量級的服務實現一個新功能,有很多好處。首先,可以防止單體應用變得更難以管理;其次,這個應用可以被獨立地開發,部署和擴展。

然而,這個方法并不能解決在舊有的單體部分遇到的問題,你還需要破壞原有的單體部分。

策略2:前后端分離

縮減單體應用的一個策略是將表現層從業務邏輯和數據訪問層中分離出來,一個典型的企業應用至少包括三種組件:

  • 表現層:?這層組件用來處理HTTP請求,實現(REST)API或者基于HTML的Web UI。在一個有著復雜的用戶接口的應用中,表現層通常有大量的代碼;

  • 業務邏輯層:?應用的核心代碼,用來實現業務規則;

  • 數據訪問層:?訪問數據庫或信息中介的組件。

在表現邏輯與業務和數據訪問邏輯之間通常有著明顯的區分。業務層有一個粗粒度的API,包含一個或多個外立面組成,外立面封裝了業務邏輯組件。這個API是自然的『縫合』,所以可以將單體分割為更小的應用,一個應用包含了表現層,另一個應用包含了業務和數據訪問層。分隔后,表現邏輯層應用可以遠程調用業務邏輯層應用,下圖展示了改造前后的架構:

這樣分隔單體應用有兩個主要好處。?首先你可以獨立地開發,部署和擴展兩個應用,?比如對于表現層開發者來說,他們可以實現用戶界面的快速迭代,A/B測試也很容易實現;?其次,這樣做會向外開放一個微服務也可以調用的遠程API。

但是這個策略只是部分解決方案,很有可能會變成兩個混亂的單體應用。需要用下面第三個策略去減少單體部分的比重。

策略3:提取服務

第三個策略的目的是將單體中的模塊,轉變為單獨的微服務。每次提取一個模塊,就改造為微服務,單體部分就縮減了。一旦你轉化了足夠的模塊,最后不管單體部分是完全消失了,還是變小成了另一個微服務,都不是問題了。

優先改造哪個模塊?

一個大型的復雜的單體應用,通常包含數十甚至上百個模塊,都可以被提取出來,選擇先提取哪個是個問題。可以從容易被提取的開始,積累微服務的經驗,然后提取那些能給你帶來最大好處的模塊。

通常提取那些頻繁變化的模塊很有用?,一旦你將這個模塊提取出來,就可以獨立開發和部署它了,可以加速開發。

另外一個就是提取那些資源需求和其它部分有很大不同的模塊。?比如將一個有內存數據庫的模塊轉變為服務,就可以把它部署在內存很大的主機上;同樣的,提取那些實現復雜算法的模塊,就可以把它部署在CPU多的主機上。總之這樣做有助于你擴展應用。

當決定了提取哪個模塊后,需要看下現有的粗粒度邊界,可以幫助你將模塊轉化為服務。比如一個只會通過異步信息和其它應用交互的模塊,就很容易能被改造為微服務。

如何提取一個模塊?

第一步是在模塊和單體之間定義一個粗粒度的接口。?由于單體和微服務的數據互相都有需求,所以它?很像一個雙向的API。但是在這個模塊和應用的剩余部分之間,有著混亂的依賴關系和細粒度的交互模式,所以實現這個API還是很有挑戰的。通過域模型實現的業務邏輯,改造起來尤其困難,因為各個域模型間的關系復雜。通常需要進行大量的代碼修改,去打破這些依賴。

一旦你實現了細粒度的接口,就可以將模塊改造為一個獨立的服務。要寫代碼實現單體和微服務間的通信,通過使用了IPC機制的API。下圖展現了一個架構在改造前,改造中和改造后的樣子:

?

在這個例子中,模塊Z是待提取的模塊。模塊X使用了Z的組件,Z又使用了模塊Y。

  1. 改造的第一步是定義一對粗粒度的API,第一個接口是模塊X調用模塊Z的入站接口,第二個是模塊Z調用模塊Y的出站接口;

  2. 第二步是將這個模塊改造為獨立的服務。入站接口和出站接口都通過IPC機制的代碼實現。可能你需要通過結合模塊Z到微服務底盤框架(用來處理橫切關注點,比如服務發現)上,來構建這個服務。

一旦你提取了這個模塊,就可以獨立地開發,部署和擴展它了。你甚至可以從頭重寫這個服務,將這個服務和單體結合起來的API代碼就成了防腐層,相當于兩個域模型之間的翻譯官。每次提取一個服務,都是向著微服務又進了一步,單體的比重會逐步縮減。

總結

將單體架構改造為微服務的過程是一種應用現代化的形式,不應該從頭重寫來實現。而是應該循序漸進地改造你的應用成為一系列微服務。有三種策略可以應用:?用微服務實現新的功能;將表現層組件從業務和數據訪問組件中分離出來;改造單體中的模塊為微服務。?隨著時間的推移,你的微服務比重會增大,你的開發團隊的靈活性和速度也會提高

轉載于:https://www.cnblogs.com/cim3221847/p/6129433.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255831.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255831.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255831.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 解決ssh連接慢的問題

備份文件 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak 編輯文件 vi /etc/ssh/sshd_config 輸入/ 查找GSSAPIAuthentication 設置如下 GSSAPIAuthentication no # 是否允許使用基于 GSSAPI 的用戶認證。默認值為"no"。僅用于SSH-2 詳細解釋 輸入/ 查找UseDNS …

ABB機器人與PC計算機控制口連接 超級終端 命令清單

條件: 9 針串口通信 RS232。 PC 啟動超級終端軟件。Windows -> Start -> Accessories -> Terminal 通信設置: 1. 波特率 9600 8 位2. 1 個停止位 沒有奇偶校驗3. 沒有 Modern 采用直接串口連接4. 使用 Xon/Xoff 通信形式當故障發生時&#xff0…

【Hibernate】Hibernate系列6之HQL查詢

HQL查詢 6.1、概述 6.2、分頁查詢 6.3、命名查詢 6.4、投影查詢-部分字段查詢 6.5、報表查詢 6.6、迫切左外連接、左外連接 6.7、迫切內連接、內連接 6.8、QBC查詢、本地查詢 轉載于:https://www.cnblogs.com/junneyang/p/5254641.html

【深度學習】——梯度下降優化算法(批量梯度下降、隨機梯度下降、小批量梯度下降、Momentum、Adam)

目錄 梯度 梯度下降 常用的梯度下降算法(BGD,SGD,MBGD) 梯度下降的詳細算法 算法過程 批量梯度下降法(Batch Gradient Descent) 隨機梯度下降法(Stochastic Gradient Descent&#xff09…

Javascript隱式轉換

亂想 javascript為什么需要隱式轉換?如果沒有會出現什么情況? 找了一圈沒有看到關于這個的討論,只好自己研究了,可能不一定正確,自行辨知。 郁悶就是郁悶在好好的,為什么要搞個隱式轉換,一般來講…

雙工位機器人 焊接夾具注意事項 o(╯□╰)o

焊接夾具設計注意事項 一套完美的夾具,需要機械設計人員正確的設計思想,良好的配件質量,鉗工負責認真的裝配質量,卡具在使用中不斷的修磨和改進,才會達到好的效果。 本人非機械設計,只是在使用焊接卡具過程中遇到了很多卡具設計上…

【公共類庫】加密解密

public static class MyEncryption{#region Md5加密/// <summary>/// 使用MD5加密/// </summary>/// <param name"str">需要加密的數據。</param>/// <param name"kind">加密類型&#xff1a;1-普通加密&#xff1b;2-密碼加…

使用JOTM實現分布式事務管理(多數據源)

使用spring和hibernate可以很方便的實現一個數據源的事務管理,但是如果需要同時對多個數據源進行事務控制,并且不想使用重量級容器提供的機制的話,可以使用JOTM達到目的. JOTM的配置十分簡單,spring已經內置了對JOTM的支持,一.<bean id"jotm" class"org.spri…

【機器學習】——《機器學習實戰》面試復習

目錄 一、機器學習概念 二、機器學習步驟 三、有監督學習 1、k-近鄰算法 核心思想 實例&#xff1a;手寫數字的識別 優缺點&#xff1a; 2、決策樹 相關概念 核心思想 一些小技巧 優缺點 3、神經網絡 4、SVM——支持向量機 核心思想 SVM和SVR的區別 ? 優缺點…

一鍵分享代碼

文章出處&#xff1a;http://share.baidu.com/code/advance 一、概述 百度分享代碼已升級到2.0&#xff0c;本頁將介紹新版百度分享的安裝配置方法&#xff0c;請點擊左側列表查看相關章節。 二、代碼結構 分享代碼可以分為三個部分&#xff1a;HTML、設置和js加載&#xff0c;…

ubuntu安裝LDAP

參考文獻&#xff1a; https://help.ubuntu.com/12.04/serverguide/openldap-server.html&#xff08;最主要的&#xff09; http://www.linuxidc.com/Linux/2011-08/40020.htm http://blog.chinaunix.net/uid-24276740-id-3360306.html 前言 在網上搜索ldap的安裝配置&#xf…

58.貪心算法練習:??最小新整數

總時間限制: 1000ms 內存限制: 65536kB 描述 給定一個十進制正整數n(0 < n < 1000000000)&#xff0c;每個數位上數字均不為0。n的位數為m。現在從m位中刪除k位(0< m)&#xff0c;求生成的新整數最小為多少&#xff1f;例如: n 9128456, k 2, 則生成的新整數最小…

ABB機器人之LOADDATA

ABB機器人之LOADDATA loaddata是用來描述連接到機器人機械接口的負載&#xff08;機器人的安裝法蘭&#xff09;。loaddata數據通常定義有效載荷或負荷&#xff08;通過指令gripload設置機器人抓手負載 或mechunitload指令設置變位機負載。loaddata通常也作為tooldata的一部分&…

【深度學習】——性能指標(ROC、MAP、AUC等)

目錄 一、分類任務性能指標 1、混淆矩陣 2、精確度ACCURACY 正確數/總數 3、查全率&#xff08;RECALL&#xff09;——真正正樣本中預測正確的比例 4、查準率&#xff08;precision&#xff09;——預測為正樣本中的預測正確的比例 5、F-score——對查準率和查全率進行結…

【深度學習】——過擬合的處理方法

目錄 一、什么是過擬合&#xff1f;&#xff08;overfitting&#xff09; 二、過擬合的表現&#xff08;判定方法&#xff09; 訓練集、測試集、驗證集區別 測試集與驗證集的區別 三、產生過擬合的原因 1、樣本方面 2、模型方面 四、避免過擬合的方法 1、樣本方面 1&…

ASP.NET頁面的字符編碼設置

在用ASP.NET寫網上支付的接口程序時&#xff0c;遇到一個奇怪問題&#xff0c;通過表單提交過去的中文全是亂碼&#xff0c;英文正常。而用asp程序進行測試&#xff0c;可以正常提交中文&#xff0c;asp頁面中有這樣的HTML代碼&#xff1a; <meta http-equiv"Content-T…

帝人製機--適合的機遇--遇到恰到好處的產品--工業機器人減速機造就一個百年企業

持之以恒是成功的必要條件&#xff0c;但是也要有恰當的土壤。日本Nabtesco(納博特斯克)舊名&#xff1a;帝人製機(TEIJINSEIKI)高性能日本RV減速機納博特斯克(Nabtesco)公司是一家居世界領先地位的精密傳動控制系統及組件製造商。目前全世界已有超過兩百萬件由Nabtesco製造的精…

Python個人項目--豆瓣圖書個性化推薦

項目名稱: 豆瓣圖書個性化推薦 需求簡述&#xff1a;從給定的豆瓣用戶名中&#xff0c;獲取該用戶所有豆瓣好友列表&#xff0c;從豆瓣好友中找出他們讀過的且評分5星的圖書&#xff0c;如果同一本書被不同的好友評5星&#xff0c;評分人數越多推薦度越高。 輸入&#xff1a;豆…

#define宏定義形式的函數導致的bug

定義了一個宏定義形式的"函數": #define SUM8(YY)\ {\ int Y YY>>2;\ ...\ } 然后使用的時候&#xff0c;傳入了一個同名的變量Y: int Y Ywin[x]; SUM8(Y) 本意是想展開成int Y Ywin[x]>>2; 但實際上#define只是把參數名(YY)替換&#xff0c;與函數…

【深度學習】——BN層(batch normalization)

目錄 一、“Internal Covariate Shift”問題 二、BatchNorm的本質思想 兩個參數r和β的意義——精髓所在 三、訓練階段如何做BatchNorm 四、BatchNorm的推理(Inference)過程 五、BatchNorm的好處 一般使用在卷積層后、激活層前 Batch Normalization作為最近一年來DL的重要…