Pattern: Database per service。
背景
如用微服務架構模式開發一個線上商店應用程式。大多數服務需要在某種資料庫中持久化資料。如,訂單服務
儲存訂單資訊,而客戶服務
儲存客戶資訊。
問題
微服務應用程式中的資料庫架構是什麼?
驅動力
- 服務必須松耦合,以便能夠獨立開發、部署和擴充套件。
- 某些業務事務必須在多個服務之間強制執行不變數。例如,
下訂單
用例必須驗證新訂單不會超出客戶的信用額度。其他業務事務需要更新由多個服務擁有的資料。 - 一些業務事務需要查詢多個服務的資料。例如,
檢視可用信用額度
用例需要查詢客戶服務獲取信用額度
,並查詢訂單服務計算未結訂單的總金額。 - 某些查詢需要關聯多個服務的資料。例如,查詢特定地區的客戶及其最近的訂單需要在客戶和訂單之間進行資料關聯。
- 資料庫有時需要複製和分片以實現擴充套件。參見擴充套件立方體。
- 不同的服務對資料儲存有不同的需求。例如,某些服務適合使用關係型資料庫,而其他服務可能需要 NoSQL 資料庫(如 MongoDB)來儲存複雜的非結構化資料,或者需要 Neo4J 來高效儲存和查詢圖資料。
解決方案
讓每個微服務的永續性資料對該服務私有,並僅透過其 API 訪問。服務的事務只涉及其自己的資料庫。
下圖展示了這一模式的結構。
服務的資料庫實際上是該服務實現的一部分。它不能被其他服務直接訪問。
有幾種方法可以讓服務的永續性資料保持私有性。你不需要為每個服務配置一個獨立的資料庫伺服器。例如,如果你使用的是關係型資料庫,可以選擇以下方式:
- 每服務私有表:每個服務擁有一組只能由該服務訪問的表。
- 每服務一個模式:每個服務擁有一個私有的資料庫模式。
- 每服務一個資料庫伺服器:每個服務都有自己的資料庫伺服器。
每服務私有表和每服務一個模式的實現開銷最低。使用每服務一個模式較為吸引人,因為它可以更加清晰地劃分所有權。一些高吞吐量服務可能需要獨立的資料庫伺服器。
建議建立屏障以強制實現模組化。例如,可以為每個服務分配不同的資料庫使用者 ID,並透過資料庫訪問控制機制(如授權)來限制訪問。如果沒有這些強制手段,開發人員可能會直接繞過服務的 API 訪問其資料。
示例
FTGO 應用程式 是一個使用這種方法的示例。每個服務都擁有資料庫憑據,這些憑據僅允許其訪問自己(邏輯)資料庫的許可權,資料庫位於共享的 MySQL 伺服器上。有關更多資訊,請參閱這篇部落格文章。
結果情境
使用每個服務一個資料庫具有以下優點:
- 有助於確保服務之間的松耦合。對一個服務資料庫的更改不會影響其他服務。
- 每個服務可以選擇最適合其需求的資料庫型別。例如,進行文字搜尋的服務可以使用 ElasticSearch,而操作社交圖的服務可以使用 Neo4j。
但這一模式也有以下缺點:
- 實現跨多個服務的業務事務並不簡單。由於 CAP 定理,分散式事務應儘量避免。此外,許多現代(NoSQL)資料庫不支援分散式事務。
- 實現跨多個資料庫的資料關聯查詢較為複雜。
- 管理多個 SQL 和 NoSQL 資料庫會增加系統複雜性。
針對跨服務事務和查詢的實現,可以採用以下模式或解決方案:
- 實現跨服務事務:使用 Saga 模式。
- 實現跨服務查詢:
- API 組合:由應用程式執行資料關聯而非資料庫。例如,一個服務(或 API 閘道器)可以先從客戶服務檢索客戶資訊,再從訂單服務查詢客戶的最近訂單。
- 命令查詢職責分離(CQRS):維護一個或多個包含來自多個服務資料的物化檢視。這些檢視由訂閱服務更新事件的服務維護。例如,線上商店可以透過維護一個將客戶與訂單關聯的檢視來實現一個查詢,用於查詢特定地區的客戶及其最近的訂單。此檢視由一個訂閱客戶和訂單事件的服務更新。
相關模式
- 微服務架構模式:引發了對這種模式的需求。
- Saga 模式:是一種實現最終一致性事務的有效方法。
- API 組合和命令查詢職責分離(CQRS):提供了實現跨服務查詢的實用方法。
- 共享資料庫反模式:描述了微服務共享資料庫時可能導致的問題。
關注我,緊跟本系列專欄文章,咱們下篇再續!
作者簡介:魔都架構師,多家大廠後端一線研發經驗,在分散式系統設計、資料平臺架構和AI應用開發等領域都有豐富實踐經驗。
各大技術社群頭部專家博主。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。
負責:
- 中央/分銷預訂系統效能最佳化
- 活動&券等營銷中臺建設
- 交易平臺及資料中臺等架構和開發設計
- 車聯網核心平臺-物聯網連線平臺、大資料平臺架構設計及最佳化
- LLM Agent應用開發
- 區塊鏈應用開發
- 大資料開發挖掘經驗
- 推薦系統專案
目前主攻市級軟體專案設計、構建服務全社會的應用系統。
參考:
- 程式設計嚴選網
本文由部落格一文多發平臺 OpenWrite 釋出!