微服務從設計到部署(七)重構單體為微服務

来源:http://www.cnblogs.com/oopsguy/archive/2017/09/29/7609561.html
-Advertisement-
Play Games

您正工作於大型複雜的單體應用程式上,這是相當不錯的機會。您開發和部署應用程式的日常經歷是緩慢而痛苦的。微服務似乎是一個遙不可及的天堂。幸運的是,有一些戰略可以用來逃離單體地獄。在本文中,我將描述如何將單體應用程式逐漸重構為一組微服務。 ...


https://github.com/oopsguy/microservices-from-design-to-deployment-chinese
譯者http://oopsguy.com

本書是關於如何使用微服務構建應用程式,這是本書的第七章,也是最後一章。第一章介紹了微服務架構模式,討論了使用微服務的優點與缺點。隨後的章節討論了微服務架構的方方面面:使用 API ​​網關進程間通信服務發現事件驅動數據管理部署微服務。在本章中,我們將介紹單體應用遷移到微伺服器的策略。

我希望這本電子書能夠讓您對微服務架構、其優點和缺點以及何時使用它有很好的瞭解。微服務架構也許很適合您的組織。

然而,您正工作於大型複雜的單體應用程式上,這是相當不錯的機會。您開發和部署應用程式的日常經歷是緩慢而痛苦的。微服務似乎是一個遙不可及的天堂。幸運的是,有一些戰略可以用來逃離單體地獄。在本文中,我將描述如何將單體應用程式逐漸重構為一組微服務。

7.1、微服務重構概述

單體應用程式轉換為微服務的過程是應用程式現代化的一種形式。這是幾十年來開發人員一直在做的事情。因此,在將應用程式重構為微服務時,有一些想法是可以重用的。

一個不要使用的策略是“大爆炸”重寫。就是您將所有的開發工作都集中在從頭開始構建新的基於微伺服器的應用程式。雖然這聽起來很吸引人,但非常危險,有可能會失敗。據 AsMartin Fowler 講到:“大爆炸重寫的唯一保證就是大爆炸!”("the only thing a Big Bang rewrite guarantees is a Big Bang!")。

您應該逐步重構單體應用程式,而不是通過大爆炸重寫。您逐漸添加新功能,並以微服務的形式創建現有功能的擴展 —— 以互補的形式修改單體應用,並且一同運行微服務和修改的單體。隨著時間推移,單體應用程式實現的功能量會縮小,直到它完全消失或變成另一個微服務。這種策略類似於在 70公裡/小時的高速公路上駕駛一輛汽車,這很具有挑戰性,但比嘗試大爆炸改寫的風險要小得多。

Martin Fowler 將這種應用現代化策略稱為殺手應用(Strangler Application)。這個名字來自於熱帶雨林中發現的葡萄樹(也稱為絞殺榕)。一棵葡萄樹生長在一棵樹上,以獲取森林冠層之上的陽光。有時,樹死了,留下一個樹形的騰。應用現代化也遵循相同的模式。我們將構建一個新的應用程式,包括了圍繞遺留應用的微服務(它將會慢慢縮小或者最終消亡)。

讓我們來看看能做到這點的不同策略。

7.2、策略一:停止挖掘

洞穴定律說到,每當您身處在一個洞穴中,您應該停止挖掘。當您的單體應用變得難以管理時,這是一個很好的建議。換句話說,您應該停止擴張,避免使單體變得更大。這意味著當您要實現新功能時,您不應該向單體添加更多的代碼。相反,這一策略的主要思想是將新代碼放在獨立的微服務中。

應用此方法後,系統架構如圖 7-1 所示。

圖 7-1、將新功能實現為單獨的服務,而不是將模塊添加到單體

除了新服務和傳統的單體,還有另外兩個組件。第一個是請求路由,它處理傳入的(HTTP)請求,類似於第二章中描述的 API 網關。路由向新服務發送與新功能相對應的請求。它將遺留的請求路由到單體。

另一個組件是粘合代碼,它將服務與單體集成。一個服務很少孤立存在,通常需要訪問單體的數據。位於單體、服務或兩者中的膠合代碼負責數據集成。該服務使用粘合代碼來讀取和寫入單體數據。

服務可以使用三種策略來訪問單體數據:

  • 調用由單體提供的遠程 API
  • 直接訪問單體資料庫
  • 維護自己的數據副本,與單體資料庫同步

粘合代碼有時被稱為防護層(anti-corruption layer)。這是因為粘合代碼阻止了服務被遺留的單體領域模型的概念所污染,這些服務具有自己的原始領域模型。粘合代碼在兩種不同的模型之間轉換。防護層一詞首先出現於埃里克·埃文斯(Eric Evans)的必讀圖書《領域驅動設計》(Domain Driven Design)中,併在白皮書中進行了改進。開發一個防護層並不是一件簡單的事。但是,如果您想要從單體地獄中走出來,這是必不可少的步驟。

使用輕量級服務來實現新功能有幾個好處。它防止單體變得更加難以管理。該服務可以獨立於單體開發、部署和擴展。可讓您創建的每個新服務體驗到微服務架構的優勢。

然而,這種方法沒有解決單體問題。要解決這些問題,您需要分解單體。讓我們來看看這樣做的策略。

7.3、策略二:前後端分離

縮小單體應用的一個策略是從業務邏輯層和數據訪問層拆分出表現層。一個典型的企業應用由至少三種不同類型的組件組成:

  • 表現層(Presentation Layer,PL) - 處理 HTTP 請求並實現(REST)API 或基於 HTML 的 Web UI 組件。在具有複雜用戶界面的應用中,表現層通常存在大量代碼。
  • 業務邏輯層(Business Logic Layer,BLL) - 作為應用程式核心,實現業務規則的組件。
  • 數據訪問層(Data Access Layer,DAL) - 訪問基礎架構組件的組件,如資料庫和消息代理。

一方面的表現邏輯和另一方的業務和數據訪問邏輯之間通常有一個完全的隔離。業務層具有由一個或多個門面組成的粗粒度 API,其封裝了業務邏輯組件。這個 API 是一個天然的邊界,您可以沿著該邊界將單體拆分成兩個較小的應用程式。一個應用程式包含表現層。另一個應用程式包含業務和數據訪問邏輯。分割後,表現邏輯應用程式對業務邏輯應用程式進行遠程調用。

重構之前和之後的架構如圖 7-2 所示。

圖 7-2、重構現有的應用程式

以這種方式拆分單體有兩個主要優點。它使您能夠獨立於彼此開發、部署和擴展這兩個應用。特別是,它允許表現層開發人員在用戶界面上快速迭代,並且可以輕鬆執行 A/B 測試。這種方法的另一個優點是它暴露了可以被您開發的微服務調用的遠程 API。

然而,這一策略只是一個局部解決方案。兩個應用程式中的一個或兩個很可能是一個無法管理的單體。您需要使用第三種策略來消除剩餘的整體或單體。

7.4、策略三:提取服務

第三個重構策略是將龐大的現有模塊轉變為獨立的微服務。每次提取一個模塊並將其轉換成服務時,單體就會縮小。一旦您轉換了足夠的模塊,單體將不再是一個問題。或者它完全消失,或者變得足夠小,它就可以被當做一個服務看待。

7.4.1、優先將哪些模塊轉換為微服務

一個龐大而複雜的單體應用由幾十個或幾百個模塊組成,所有模塊都是提取的候選項。弄清楚要先轉換哪些模塊往往存在一定的挑戰。一個好的方法是從容易提取的幾個模塊開始。您將得到微服務的相關經驗,特別是在提取過程方面。之後,您應該提取那些能給您最大利益的模塊。

將模塊轉換為服務通常是耗時的。您想按照您將獲得的利益對模塊進行排列。提取頻繁更改的模塊通常是有益的。一旦將模塊轉換為服務,您就可以獨立於單體開發和部署,這將加快開發工作。

提取這些資源需求與單體的其他模塊有顯著不同的模塊也是有益的。例如,將有一個有記憶體資料庫的模塊轉換為服務是很有用的,這樣可以部署在具有大量記憶體的主機上,無論是裸機伺服器、虛擬機還是雲實例。同樣,提取實現了計算昂貴演算法的模塊也是值得的,因為該服務可以部署在具有大量 CPU 的主機上。通過將具有特定資源需求的模塊轉換為服務,您可以使應用程式更加容易、廉價地擴展。

當找到要提取的模塊時,尋找現有的粗粒度邊界(又稱為接縫)是有用的。它們使模塊轉成服務變得更容易和更連廉價。有關這種邊界的一個例子是一個僅通過非同步消息與應用程式的其他部分進行通信的模塊。將該模塊轉變為微服務相對比較廉價和簡單。

7.4.2、如何提取模塊

提取模塊的第一步是在模塊和單體之間定義一個粗粒度的介面。因為單體需要服務擁有的數據,它很可能是一個雙向 API,反之亦然。由於模塊和應用程式的其餘之間存在著複雜的依賴關係和細粒度的交互模式,因此實現這樣的 API 通常存在挑戰。由於領域模型類之間的眾多關聯,使用領域模型模式來實現的業務邏輯尤其具有挑戰性。您通常需要進行重大的代碼更改才能打破這些依賴。圖 7-3 展示了重構。

圖7-3、單體模塊可以轉換為微服務

一旦實現了粗粒度的介面,您就可以將模塊變成獨立的服務。要做到這點,您必須編寫代碼以使單體和服務通過使用進程間通信(IPC)機制的 API 進行通信。圖 7-3 顯示了重構前、重構中和重構後的架構。

在此例中,模塊 Z 是要提取的候選模塊。其組件由模塊 X 使用,並且它使用了模塊 Y。第一個重構步驟是定義一對粗粒度的 API。第一個介面是一個使用模塊 X 來調用模塊 Z 的入站介面。第二個介面是一個使用模塊 Z 調用模塊 Y 的出站介面。

第二個重構步驟是將模塊轉換為一個獨立服務。入站和出站介面使用 IPC 機制的代碼來實現。您將很可能需要通過將 Module Z 與 Microservice Chassis 框架相結合來構建服務,該框架負責處理諸如服務發現之類的橫切點。

一旦您提取了一個模塊,您就可以獨立於單體和任何其他服務開發、部署和擴展其他服務。您甚至可以從頭開始重寫服務;在這種情況下,整合服務與單體的 API 代碼成為在兩個領域模型之間轉換的防護層。每次提取服務時,您都會朝微服務方向邁近一步。隨著時間的推移,單體將縮小,您將擁有越來越多的微服務。

7.5、總結

將現有應用程式遷移到微服務的過程是應用程式現代化的一種形式。您不應該從頭開始重寫您的應用來遷移到微服務。相反,您應該將應用程式逐漸重構為一組微服務。可以使用這三種策略:將新功能實現為微服務;從業務組件和數據訪問組件中分離出表現組件;將單體中的現有模塊轉換為服務。隨著時間推移,微服務的數量將會增長,您的開發團隊的靈活性和速度也同樣會增加。

微服務實戰:用 NGINX 馴服單體

by Floyd Smith

如本章所述,將單體轉換為微服務可能是一個緩慢而具有挑戰性的過程,但這同樣具有許多好處。使用 NGINX,您可以在實際開始轉換過程之前獲得微伺服器的一些優勢。

您可以通過將 NGINX 放在您現有的單體應用之前,以節省遷移微服務所花費的大量時間。以下簡要說明與微服務有關的好處:

  • 更好地支持微服務 — 如第五章最後欄目所述,NGINX 和 NGINX Plus 具有利於開發基於微服務的應用的功能。當您開始重新設計單體應用時,由於 NGINX 的功能,您的微服務將執行得更好、更易於管理。
  • 跨環境的功能抽象 — 從您管理的伺服器到各種公共雲、私有雲和混合雲上將功能遷移到 NGINX 作為反向代理伺服器可以減少部署在新的環境中的設施數量變化。這補充擴展了微服務所固有的靈活性。
  • NGINX 微服務參考架構可用性 — 當您遷移到 NGINX 時,您可以借鑒 NGINX 微服務參考架構(MRA,Microservices Reference Architecture),以便在遷移到微服務之後定義應用程式的最終結構,並根據需要使用的 MRA 部分應用於您創建的每個新的微服務。

總而言之,實現NGINX作為您的轉型的第一步,將壓倒您的單片應用程式,使其更容易獲得微服務的所有優勢,併為您提供用於進行轉換的模型。您可以瞭解有關 MRA 的更多信息,並獲得 NGINX Plus 的免費試用版。

此系列全部譯文(完結)

https://github.com/oopsguy/microservices-from-design-to-deployment-chinese


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當前環境 代碼地址 git 地址:https://github.com/jasonGeng88/java-network-programming 背景 前不久,上線了一個新項目,這個項目是一個壓測系統,可以簡單的看做通過回放詞表(http請求數據),不斷地向服務發送請求,以達到壓測服務的目的。在測試 ...
  • 【卻說那妖精與大聖鬥經半日,不分勝敗。行者把棒丟起,叫一聲“變!”就以一變十,以十變百,以百變千,半天里,好似蛇游蟒攪,亂打妖邪。妖邪慌了手腳,將身一閃,化道清風,即奔碧空之上逃走。行者念聲咒語,將鐵棒收做一根,縱祥光一直趕來。】 在西游記第九十五回【假合真形擒玉兔 真陰歸正會靈元】中,孫行者“毆打 ...
  • 1.3 網路編程模型與服務治理 服務治理和服務劃分密不可分。服務之間既然進行了劃分,那麼服務之間就要進行通信。當今服務整個鏈路中最耗時的不是鏈路節點本身,而是節點間的通信。理解網路編程模型可以更好的進行服務治理。 網路編程模型的選擇與服務治理關心的性能指標,各種參數的配置,維護的上下游之間是怎樣的關 ...
  • 1.uml活動圖 活動圖是uml用來對系統動態行為建模的另一種建模方法。描述活動的順序,展現活動從一個活動到另一個活動的流程。活動圖的本質是流程圖。 2.活動圖的繪製 2.1 活動圖的基本模型 活動圖的組成元素:活動,轉換,分支,合併,分叉,匯合,泳道。 如圖:一個簡單的活動圖。 2.2活動的表示 ...
  • 前臺: 支持三套模版, 可以在後臺切換 系統介紹: 1.網站後臺採用主流的 SSM 框架 jsp JSTL,網站後臺採用freemaker靜態化模版引擎生成html 2.因為是生成的html,所以訪問速度快,輕便,對伺服器負擔小 3.網站前端採用主流的響應式佈局,同一頁面同時支持PC、平板、手機(三 ...
  • 最近重看java編程思想,感覺收穫頗多。 看到在繼承處提到的策略模式不禁想到之前的一個乒乓球機器人的項目中的一個環節,感覺策略模式能很好的解決,所以在這裡寫一個小demo 情景: 由機器人視覺採集到一些點後,對乒乓求得軌跡進行預測,併在這條軌跡中取一個最佳擊球點。 之前我是直接在一個類中通過對不同方 ...
  • 定義: 表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。 UML類圖: 具體代碼: 模塊說明:Visitor:抽象類或者介面,聲明visit方法中的參數定義哪些對象是可以被訪問的。ConcreteVisitor:具體訪問者實現的對象,實現被添加 ...
  • 1.2 服務治理和架構 我在矽谷那段時間,每天早上都單獨要一份omelet,就是美式煎蛋。2個雞蛋和黃油是必選的,另外需要自己在需要放的材料上打鉤,有多種芝士可選,另外還可以勾選洋蔥,蘑菇,培根,西蘭花等。 回國之後,經常也會自己這樣做早餐,只是總會在擺盤時,用圓火腿斜切兩片,然後將這這個片再四六分 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...