【架構與設計】常見微服務分層架構的區別和落地實踐

来源:https://www.cnblogs.com/jingdongkeji/archive/2023/04/18/17329488.html
-Advertisement-
Play Games

軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,並遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ...


作者:京東科技 康志興

前言

從強調內外隔離的六邊形架構,逐漸發展衍生出的層層遞進、註重領域模型的洋蔥架構,再到和DDD完美契合的整潔架構。架構風格的不斷演進,其實就是為了適應軟體需求越來越複雜的特點。

可以看到,越現代的架構風格越傾向於清晰的職責定位,且讓領域模型成為架構的核心。

基於這些架構風格,在軟體架構設計過程中又有非常多的架構分層模型。

傳統三層架構

傳統服務通常使用三層架構:

• 門面層:作為服務暴露的入口,處理所有的外部請求。部分情況下,門面層甚至不需要單獨定義對象而是直接使用服務層的實體定義。

• 服務層:作為核心業務層,包含所有業務邏輯。並對基礎層能力進行簡單組合提供一定的能力復用。通常服務層會進行實體定義來防止下層對象體直接暴露給外部服務,導致底層任何變化都有可能直接傳遞到外部,非常不穩定。

• 基礎層:用來存放dao和外部rpc服務的封裝,二者可以拆分為不同的module,也可合二為一,以不同package進行隔離。

三層架構特點就是簡單,適用於一些無複雜業務場景的小型應用,或者“數據不可變”作為基礎原則的DOP(面向數據編程)服務。

但是當業務場景稍微複雜一些、調用層級較多時,可復用性、可維護性就都非常差了,很多代碼都耦合在一起,牽一發動全身。

DDD架構

DDD架構可以看做是整潔架構的一種實現,分層職責如下:

• 適配層:用來做外部不同端請求的適配器,隔離不同端的協議差異,包裝不同端不同樣式的響應體。

• 應用層:用例、任務入口、消息隊列監聽均在這一層,可以理解為業務流程的入口,通過聚合根的構造執行相應的命令操作。

• 領域服務層:包含核心的領域服務定義,並定義了gateway來做一層依賴倒置,使基礎設施層僅做實現。

• 基礎設施層包含一切基礎能力:資料庫、ES、遠程調用封裝等等。

優點

• 核心穩定:領域模型在依賴鏈上是頂層角色,不依賴任何其他模塊,所以極其穩定。其他任何業務域、存儲、邊緣能力的變化都不會對領域模型造成影響。

• 敏捷:適合不同團隊一起開發和維護而不會產生衝突。

• 可拆分:當有屆上下文隨著演進逐漸膨脹時,很容易拆分成微服務。

• 可擴展:添加新的功能非常簡單,從而使得開發人員能夠更快的部署和調整。

• 可演進:良好的可測試性帶來非常低的重構成本,不會隨著不斷迭代導致項目成為難以修改的“大泥球”。

如此多的優點自然帶來明確的缺點

• 專業性要求較高:需要對業務、架構原則理解深刻的人員進行設計和維護,不恰當的領域模型將使後續迭代極為痛苦。

• 開發成本高:複雜的架構設計,更多的架構分層,自然帶來代碼行數的指數級增長。尤其是項目前期的開發任務變得異常繁重。

• 不再適合簡單的業務場景:實現一個簡單的CRUD顯得過於複雜。

• 改變決策困難:嘗試使用整潔架構需要和團隊的管理層和其他成員達成一致,這往往需要非常強大的說服力。如果在架構演進過程中想切換回其他架構模式也十分困難,幾乎是整個項目級別的重構工作。

簡單的微服務分層架構

基於六邊形架構規範的介面適配原則和防腐理念,同時借鑒了CQRS模式的優點,我們定義了一個簡單的微服務分層架構。

分層定義如下:

• 門面層:作為程式的入口,通過包隔離來存放JSF服務、Rest服務、定時任務和MQ消費,其中對外提供服務的介面定義存放在單獨的api包中。該層的請求定義命名以Request結尾,響應體命名以Response結尾。

• 領域服務層:每一個領域服務存放在單獨的module中,並通過單獨的api包對外暴露能力。該層的命令請求定義命名以Command結尾,查詢請求定義命名以Query結尾,響應體命名以Dto結尾。

• 基礎設施層:存放資料庫、ES、遠程調用服務的封裝。該層的持久化數據定義命名以Po結尾。遠程命令服務入參命名以RpcCommand結尾,遠程查詢服務入參命名以RpcQuery結尾,響應體命名以RpcDto結尾。

最佳實踐

  1. 命令服務必須訪問領域服務層,允許簡單查詢直接調用基礎設施層。

  2. 參數校驗、請求出入參日誌、審計日誌記錄、TraceID預埋、異常處理等非核心業務能力均由公共組件完成,減少項目內部的邊緣能力代碼。

  3. 由於在門面層進行統一的異常處理,非必要時無需在項目中進行大面積的try-catch,讓代碼更清爽。

  4. 實際開發過程中,門面層、領域服務層和基礎設施層均有各自的實體定義,跨層調用的對象體轉換使用MapStruct組件來減少手寫映射代碼的工作量。

  5. 數據層使用Fluent-Mybatis,最大好處是減少後期迭代中,數據對象增減欄位時修改Mapper的成本。

優點

1. 開發效率

簡單的業務開發過程中,相比較書寫核心業務邏輯,更多的工作量幾乎都是來自處理跨層調用時對象轉換和Mapper定義,通過MapStruct和Fluent-Mybatis等組件的使用(也許再加上GitHub Copilot

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

-Advertisement-
Play Games
更多相關文章
  • 好家伙, 代碼已開源 Git: https://gitee.com/tang-and-han-dynasties/panghu-planebattle-esm.git NPM: panghu-planebattle-esm - npm (npmjs.com) 現在,比如說,我用Vue寫好了個人博客主 ...
  • Vue3 的狀態管理主要是通過 Vuex 4 來實現。Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式,它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。 在Vue3的狀態管理中,以下是各個屬性的作用: state:存儲應用程式中的狀態數據。它 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 當今Web開發中,數據安全是一個至關重要的問題,為了確保數據的安全性,我們需要使用加密技術。JavaScript作為一種客戶端編程語言,可以很好地為數據進行加密。在本篇文章中,我們將為你提供一個常規JavaScript加密大全,以及案例代 ...
  • 在Vue3中,路由的基本配置是通過使用Vue Router庫來實現的。以下是Vue3中路由的基本配置步驟: 安裝Vue Router 使用npm或yarn在項目中安裝Vue Router: npm install vue-router // 或者 yarn add vue-router 創建路由實例 ...
  • 在Vue3中,計算屬性可以使用computed函數來定義。 computed函數接受兩個參數:第一個參數是一個函數,該函數返回計算屬性的值;第二個參數是一個可選的配置對象,可以包含getter和setter函數,以及控制計算屬性緩存的緩存配置。 Vue3中的計算屬性與Vue2中的計算屬性相比有以下幾 ...
  • 拉去遠程分支代碼報錯:fatal: refusing to merge unrelated histories造成的原因是: 1、本地項目copy 其他項目的結構把.git 文件可拷貝過來了 且覆蓋了自己當前目錄的 .git 文件,然後將當前分支合遠程分支合併 因為兩個 .git 文件儲存庫的歷史數 ...
  • 後臺管理系統在實際開發中,表格如果在一定高度出現滾動條。 這時如果對錶格行數據進行編輯或者拖拽排序操作,數據刷新後滾動條會預設回到頂部,這樣體驗會不太好。 如果想保留在當前位置可以這樣操作: 1.el-table標簽添加ref屬性 <el-table :data="tableData" v-load ...
  • #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實例。 // 其他有用的實例變數寫在這裡 //構造器聲明為私有,只有Singleton可以實例化這個類! ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...