如何把單體式應用拆解成微服務?【上】

来源:https://www.cnblogs.com/itlaobingge/archive/2019/12/25/12095774.html
-Advertisement-
Play Games

微服務是當下最流行的應用架構技術了,它跟容器服務、DevOps合稱雲時代的三劍客,可以幫我們化解業務發展過快導致的產品迭代壓力,讓我們可以自由選擇最適合團隊的技術棧,讓系統能夠承載互聯網海量用戶的訪問,讓我們可以更加輕鬆地運維大型的互聯網系統。近些年在廠商、社區和用戶等各方努力推動下,微服務相關的理... ...


昨日好評博文:如何設計出優美的Web API?

截止目前閱讀量近 2000,獲得好評無數,小伙伴們不要錯過哦!

 

微服務是當下最流行的應用架構技術了,它跟容器服務、DevOps合稱雲時代的三劍客,可以幫我們化解業務發展過快導致的產品迭代壓力,讓我們可以自由選擇最適合團隊的技術棧,讓系統能夠承載互聯網海量用戶的訪問,讓我們可以更加輕鬆地運維大型的互聯網系統。近些年在廠商、社區和用戶等各方努力推動下,微服務相關的理論和產品都日趨成熟,不同語言的微服務開發及治理套件(例如:Spring Cloud/Dubbo等)讓我們從零開始搭建微服務變得非常簡單快捷,那我們是否就此可以全面進入微服務時代呢?

微服務的演進成熟需要時間,我們熟悉掌握這套新技術也需要時間,除此之外機房裡面還跑著大量的單體式應用,它們需要繼續維護和升級,任何時候我們都不可能拋開歷史輕鬆上陣。這些單體式應用還擔負著公司的核心業務,全部推倒重來、休克式重構是不可取的,投入大周期長,風險完全不可控。我們必須學會邊行車邊換胎的技能,在不影響現網業務的前提下推動微服務改造,讓老系統煥發新的生命力,繼續支持業務下一個十年的發展。本文將跟你一起探討微服務改造相關的經驗方法,讓你更加從容地擁抱微服務!

  • 1. 邊行車邊換胎三步走演進策略

如何從單體式應用演進至微服務呢?這些單體式應用都存在很長時間了,經過這麼長時間的修修補補,體量規模都比較大,尤其是經過幾波人交接維護,業務邏輯也變得異常複雜。同時,它們都線上對外提供服務,全部推倒重建的可能性微乎其微,休克式重構投入大周期長,風險也不好控制,還會影響業務對外服務的連續性。從現實情況出發,最可行的架構優化方案就是漸進式的微服務改造,按照業界的最佳實踐和個人經驗,該演進策略主要包括三個關鍵步驟:

  • 將所有新特性都構建成微服務,遏制單體式應用的生長;
  • 在微服務和單體式應用之間構建反腐層,防止老系統腐化新系統;
  • 按照特定的優先順序由外而內逐步瓦解單體式應用。

 

  • 1.1 新建微服務

通常單體式應用所採用的技術相對較老舊,維護這些系統的同事缺少機會學習實踐當前主流的技術,久而久之就跟不上主流技術的發展,在晉升、加薪和跳槽時都缺乏競爭力,這會影響到個人的價值。隨著系統規模越來越龐大,更新升級和運營維護的難度越來越大,每次發版都要加班加點和心驚膽戰,逐漸滿足不了業務快速發展的需要。在單體式架構之下,團隊無法利用不同技術棧的優勢解決不同場景下的問題,即使解決了問題也是事倍功半。

當意識到有必要將單體式應用改造成微服務時,我們通常會認為改造就是將單體式應用一塊一塊地敲下來改成微服務,這種想法是最直接的,但難度和風險也是最大的。改造初始我們對微服務相關技術也比較生疏,再加上拆解單體式應用本身的難度,雙重困難疊加往往會導致改造失敗或延期。

最靠譜的策略是先停止往單體式應用裡面添加新的特性,所有新特性都構建成微服務,從而遏制單體式應用繼續生長。新特性通常不會太複雜,新建微服務也要比從單體式應用上剝離微服務容易一些,藉助這個過程讓團隊逐漸熟悉掌握微服務技術棧,從小規模練兵再到全面鋪開。常見的微服務架構如下圖所示,主要包含以下幾大必備組件:

微服務框架

  • 註冊中心,提供微服務的註冊、發現和狀態監測等功能;
  • 配置中心,解耦代碼與配置,通過統一的遠程配置中心管理每個微服務的配置數據,支持動態修改和立即生效等;
  • 治理中心,依賴註冊中心和配置中心,提供服務降級、服務熔斷、流量控制、灰度管理等功能;
  • API網關,將每個微服務匯聚一起對外提供服務,網關本身會提供安全鑒權、服務路由、流量控制、計量計費等橫切麵功能。 
  • 1.2 構建反腐層

新特性全部構建成了微服務,但老特性還依舊在單體式應用當中,許多業務還需要新舊系統彼此協作才能完成,那麼微服務和單體式應用之間還存在彼此交互。但新舊系統對外服務時所採用的協議可能不同,例如:採用Spring Cloud框架開發的微服務主要以RESTful HTTP API對外服務,採用Dubbo框架開發的微服務以Dubbo協議對外服務,而單體式應用可能以Web Service、EJB T3、不規範HTTP API等形式對外服務。除了協議不同之外,新舊系統對領域模型的定義也可能不同,包括名稱和屬性等,如何調和微服務和單體式應用的不同呢?

在微服務和單體式應用之間構建一道反腐層,這或許是最切實可行的辦法。通過反腐層完成新舊系統的對接集成,又可以避免舊系統領域模型對新系統的干擾,讓彼此保持松耦合狀態,阻止舊系統的腐爛蔓延至新系統。反腐層還可以對單體式應用進行服務化封裝,讓其像微服務一樣以RESTful HTTP API的方式對外服務。反腐層支持雙向通訊,重點解決新舊系統對接集成、協議適配和模型轉換等問題,按照此功能定位我們可以將反腐層劃分成三個模塊:

  • 外觀(Facade),經典設計模式,作為舊系統所有服務介面的門面,簡化新舊系統對接的複雜度;
  • 適配器(Adapter),經典設計模式,向新系統提供所需的服務實體,負責請求和應答的協議適配;
  • 轉換器(Translator),負責請求和應答中新舊系統領域模型的轉換。

由於單體式應用的架構較為簡單,因此在設計之初它們很少考慮系統集成相關的設計,通常一個應用下的不同服務擁有各自的入口,外觀(Facade)就是解決此問題的,統一單體式應用對外服務的格式,像微服務一樣以RESTful HTTP API的方式對外服務,規範介面的協議類型、URL命名和報文格式等。如果舊系統不屬於我們維護,那反腐層就需要包含Facade模塊,微服務通過它對接舊系統。如果舊系統也是由我們自己維護,那建議將Facade模塊構建在單體式應用內部,微服務通過Adapter模塊對接舊系統。

  • 1.3 圍剿單體式應用

在舊系統周邊構建微服務,遏制舊系統的不斷生長,然後再從舊系統逐步剝離出微服務,最後完成對單體式應用的絞殺。優良的微服務設計同樣遵循高內聚、低耦合原則,將關聯緊密的行為封裝進一個微服務當中,從而可以減少需求變更所影響的範圍。只要服務契約不發生改變,那對單個微服務的升級改造都不會影響到其他服務,因此可以發佈更少的服務來快速地滿足業務需求,並降低同時部署多個微服務時帶來的風險。在從單體式應用剝離微服務之前,我們先看看功能模塊之間的邊界有哪些類型:

  • 技術邊界:將系統按照技術棧的不同劃分,形成兩個部件的邊界。它們所採用的技術大相徑庭,對開發人員的技能要求不同。業界將此種架構叫做洋蔥架構,擁有許多水平分層,不利於改造成微服務。
  • 地域邊界:按照組織分佈的地域劃分,相對較容易改造成微服務。
  • 業務邊界:按照業務類型劃分,最適合作為微服務的邊界類型。

領域驅動設計(DDD)理論提出了有界上下文(Bounded Context)概念,這是我們釐清服務邊界的有效工具,我們可以藉助它從單體式應用上剝離微服務。因此,單體式應用的微服務化改造,亦或新建微服務,我們都離不開業務專家的支持,通過他們確定有界上下文的劃分,從而設計出好的微服務。

  • 2. 隔離網關接管新舊系統間交互

在前面章節中我們已經知道在微服務改造過程中需要構建反腐層,那在實際項目當中反腐層會以什麼樣的形態存在呢?通常我們會將反腐層設計成隔離網關,以單獨的進程運行,在隔離網關內部實現Facade、Adapter和Translator等功能模塊。隔離網關不需要從零開始建設,我們可以在Nginx、Kong、Zuul等開源中間件基礎上擴展,它們都支持插件化或過濾器等擴展定製模式,我們很容易實現反腐層需要的功能。

隔離網關

通過反腐層(隔離網關)微服務可以與單體式應用進行正常通信,同時彼此之間保持松耦合,單體式應用可以不用做傷筋動骨地改動,微服務可以採用最新的技術獨立演進,但這種方案下這些遺留的單體式應用是無法享受到雲原生帶來的好處。有沒有一種方案可以讓這些遺留系統也享受到服務發現、流量控制、服務熔斷、服務降級等新特性呢?

Service Mesh,下一代微服務架構,可以給我們帶來更加完善的解決方案,它將原先通過微服務開發框架(例如:Spring Boot等)侵入到應用內部的服務治理等功能模塊封裝進了Sidecar,與應用結對部署,作為獨立的進程存在,這樣可以做到與應用松耦合,架構上更加靈活,可以支持微服務治理相關基礎設施的獨立升級部署,還可以支持多語言。如果在Sidecar基礎上再擴展隔離網關的功能,那遺留的單體式應用也可以更加融入微服務架構了。

Sidecar

 

  • 3. 單體式應用拆解微服務的方法

本章節我們將梳理從單體式應用剝離微服務的一些常見場景和方案。在談具體案例之前,我們有必要先瞭解一下業界最佳實踐的經驗總結,它主要包含以下幾個基本步驟:

  • 識別出某個業務板塊的上下文邊界,這是拆解單體式應用的關鍵步驟。微服務是按照業務來劃分和組織的,在動手拆解之前先要理清當前一個單體式應用提供了哪些業務功能,例如:用戶管理、商品展示、訂單管理、支付管理和物流管理等,按照垂直方向劃分出來的功能板塊都可以改造成微服務。具體操作時大部分編程語言都提供了命名空間(NameSpace)特性,我們在重構過程中可以藉助它將同一個上下文相關的代碼歸集在一起,然後從整個工程中將其拆解出來形成微服務。
  • 釐清業務功能模塊之間的依賴,儘量減少依賴關係,從變化頻繁、投入產出比高的模塊開始剝離,這樣可以逐步緩解日常開發的進度壓力。經過依賴關係的梳理,冗餘的依賴將會被消除,剩下的依賴將會從進程內部的函數調用改造成進程之間的RESTful HTTP API調用。
  • 拆解數據,包括數據訪問層和資料庫表等。除了代碼,數據也要被拆解,數據訪問層要被打散到不同的命名空間當中,資料庫表之間的外鍵依賴需要被清理消除等。

從業務開始,再到代碼,最後才是數據,這就是上述三個步驟的關鍵。業務是所有代碼和數據的源頭,面向對象設計(OOD)和領域驅動設計(DDD)是做好微服務設計的專業技能,而用好這兩項技能的前提就是對業務有深刻的洞悉,在()篇中我們將一起來看看具體的拆解場景,敬請期待!今天先分享到這裡,如果你覺得有價值,麻煩動動手指點下文 「 推薦 」按鈕讓更多小伙伴可以看到,我也會更加有動力堅持分享。另外,老兵哥我後續還會分享職業規劃、應聘面試、技能提升、影響力打造等經驗,歡迎 關註 本專欄或歪信公主號 「 IT老兵哥 」

微信公眾號「 IT老兵哥 」

關註「 IT老兵哥 」,賦能程式人生!

  • 軟技能類熱點文章:
  1. “花式”裁員套路深,你知道嗎?
  2. 遭遇裁員,如何渡過心理危機?
  3. 如何在寒冬中找到好工作?
  4. 2C 還是 2B,跟找工作有什麼關係?
  5. 大公司 vs 小公司,你會選哪個?
  6. 記住這一點,不怕找不到好工作!
  7. 跳槽,跳還是不跳,該怎麼跳?
  8. 程式員“求包養”攻略揭秘
  9. 很努力了,為什麼我還在原地踏步?

 

  • 硬技能類熱點文章:
  1. 如何設計出優美的Web API?
  2. 程式員必須懂的架構入門課
  3. 從程式員到架構師,有捷徑嗎?
  4. 圖解 Spring:HTTP 請求的處理流程與機制【1】
  5. 圖解 Spring:HTTP 請求的處理流程與機制【2】
  6. 圖解 Spring:HTTP 請求的處理流程與機制【3】
  7. 圖解 Spring:HTTP 請求的處理流程與機制【4】
  8. 圖解 Spring:HTTP 請求的處理流程與機制【5】
  9. 如何正確使用 Spring Cloud?【上】
  10. 如何正確使用 Spring Cloud?【中】
  11. 如何正確使用 Spring Cloud?【下】
  12. Spring 核心技術與產品理念剖析【上】
  13. Spring 核心技術與產品理念剖析【下】

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

-Advertisement-
Play Games
更多相關文章
  • 前言 一個ECMAScript標準的製作過程,包含了Stage 0到Stage 4五個階段,每個階段提交至下一階段都需要TC39審批通過。本文介紹這些新特性處於Stage 3或者Stage 4階段,這意味著應該很快在瀏覽器和其他引擎中支持這些特性。 一、類的私有變數 最新提案之一是在類中添加私有變數 ...
  • 案例:滾動條 html框架分為4部分,最外面的div, 放文字的div, 裝滾動條的div層,以及滾動條本身放在一個div裡面 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> ...
  • Javascript聲明變數的,雖然用var關鍵字聲明和不用關鍵字聲明,很多時候運行並沒有問題,但是這兩種方式還是有區別的。可以正常運行的代碼並不代表是合適的代碼。 varnum=1; 是在當前域中聲明變數。如果在方法中聲明,則為局部變數(localvariable),如果是在全局域中聲明,則為全局 ...
  • 現在學前端的人是越來越多,學習質量也是參差不齊。過來人的身份告訴你,如果你還沒有下定決心花時間去學習Web前端,那也可以先找些視頻學習下,Web前端開發有哪些常見技術點!接下來,就看看Web前端開發有哪些常見技術點! 1、你有哪些性能優化的方法? (1)減少http請求次數:CSSSprites,J ...
  • 實際應用中,目標字元串的生成可能需要多個數據的拼接。 由於應用頻繁,幾乎是所有編程語言都必須掌握的操作,當然每種語言具有各自特點。 本文將通過代碼實例詳細介紹一下JavaScript如何實現字元串拼接操作。 一.使用加號()拼接: 加號不但可以實現算數運算,也可以實現字元串拼接操作。 代碼實例如下: ...
  • 1 .window.onload //表示頁麵包含圖片等文件在內的所有元素都載入完成。 2 document.ready //函數只需對 DOM 樹的等待,而無需對圖像或外部資源載入的等待,從而執行起來更快。 3 document.onreadystatechange //當頁面載入狀態改變的時候執 ...
  • Vue.js 入門:從零開始做一個極簡 To Do 應用 寫作時間:2019 12 10版本信息:Vue.js 2.6.10官網文檔: "https://cn.vuejs.org/" 前言 學習 Vue 的最佳方式之一是「請立刻查閱 Vue.js 的 "官方文檔" 」,簡單看一下「基礎」部分,配合本 ...
  • CISC的英文全稱為“Complex Instruction Set Computer”,即“複雜指令系統電腦”,從電腦誕生以來,人們一直沿用CISC指令集方式。早期的桌面軟體是按CISC設計的,並一直沿續到現在。目前,桌面電腦流行的x86體繫結構即使用CISC。微處理器(CPU)廠商一直在走 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...