微服務設計模式 - 快速指南



微服務設計模式 - 概述

微服務是一種基於服務的應用程式開發方法。在這種方法中,大型應用程式將被分解成最小的獨立服務單元。微服務是透過將整個應用程式劃分為相互連線的服務集合來實現面向服務架構 (SOA) 的過程,其中每個服務只滿足一個業務需求。

微服務的概念

在面向服務架構中,整個軟體包將被細分為小型、相互連線的業務單元。這些小型業務單元將使用不同的協議相互通訊,從而為客戶端提供成功的業務。現在問題是,微服務架構 (MSA) 與 SOA 有何不同?簡單來說,SOA 是一種設計模式,而微服務是實現 SOA 的一種實現方法,或者可以說微服務是一種 SOA。

以下是我們在開發面向微服務的應用程式時需要記住的一些規則。

  • 獨立性 - 每個微服務都應該是獨立部署的。

  • 耦合性 - 所有微服務都應該鬆散耦合,這樣一來,一個微服務的更改不會影響其他微服務。

  • 業務目標 - 整個應用程式的每個服務單元都應該是最小的,並且能夠實現一個特定的業務目標。

為了應用這些原則,必須處理某些挑戰和問題。微服務設計模式討論了這些常見問題,並提供了相應的解決方案。在接下來的部分中,我們將討論問題以及使用適用的設計模式的解決方案。

與微服務相關的設計模式分為五大類。

  • 分解設計模式 - 將應用程式分解成更小的微服務。分解設計模式提供瞭如何以邏輯方式進行分解的見解。

  • 整合設計模式 - 整合設計模式處理應用程式的整體行為。例如,如何在一個呼叫中獲取多個服務的多個結果等。

  • 資料庫設計模式 - 資料庫設計模式處理如何為微服務定義資料庫架構,例如每個服務是否應該擁有一個單獨的資料庫或使用共享資料庫等等。

  • 可觀察性設計模式 - 可觀察性設計模式考慮日誌記錄、效能指標等的跟蹤。

  • 橫切關注點設計模式 - 橫切關注點設計模式處理服務發現、外部配置、部署方案等。

按業務能力分解

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。當使用微服務架構構建大型複雜應用程式時,主要問題是如何設計鬆散耦合的微服務,或者如何將大型應用程式分解成小型鬆散耦合的服務?

解決方案

我們可以為特定的業務能力定義一個微服務。業務能力是指旨在創造價值的業務活動。業務能力可以被稱為業務物件。例如:

  • 訂單管理 - 訂單管理業務能力指的是訂單。

  • 客戶管理 - 客戶管理業務能力指的是客戶。

業務能力可以進一步細分為多層層次結構。例如,訂單管理可以將交付、庫存、服務等作為業務能力。

示例

考慮一個線上書店的例子。它可以具有以下業務能力和相應的微服務:

  • 圖書目錄管理

  • 庫存管理

  • 訂單管理

  • 保修管理

Decompose By Business Capability Design Pattern

優點

  • 穩定的架構 - 由於業務能力是穩定的,因此這種架構非常穩定。

  • 跨職能團隊 - 開發團隊獨立工作,是跨職能的,並且圍繞功能特性而不是技術特性進行組織。

  • 鬆散耦合的服務 - 開發的服務將是鬆散耦合且具有內聚性的。

缺點

  • 需要很好地理解業務 - 需要在理解業務之後識別業務能力。理解組織結構會有所幫助,因為組織是基於其能力構建的。

  • 需要高級別的領域模型 - 需要業務領域物件,因為它們對應於業務能力。

按子域分解

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。當使用微服務架構構建大型複雜應用程式時,主要問題是如何設計鬆散耦合的微服務,或者如何將大型應用程式分解成小型鬆散耦合的服務?

解決方案

我們可以根據領域驅動設計 (DDD) 子域定義微服務。DDD 將業務視為一個領域,一個領域可以有多個子域。現在每個子域都指不同的領域。例如:

  • 訂單管理 - 訂單管理子域指的是訂單。

  • 客戶管理 - 客戶管理子域指的是客戶。

子域可以使用以下標準進一步分類:

  • 核心域 - 最重要且是應用程式的關鍵差異化因素。

  • 支撐域 - 與業務相關,用於支援業務活動。

  • 通用域 - 不特定於業務,但用於增強業務運營。

示例

考慮一個線上書店的例子。它可以具有以下子域和相應的微服務:

  • 圖書目錄管理

  • 庫存管理

  • 訂單管理

  • 保修管理

Decompose By Subdomain Design Pattern

優點

  • 穩定的架構 - 由於業務子域是穩定的,因此這種架構非常穩定。

  • 跨職能團隊 - 開發團隊獨立工作,是跨職能的,並且圍繞功能特性而不是技術特性進行組織。

  • 鬆散耦合的服務 - 開發的服務將是鬆散耦合且具有內聚性的。

缺點

  • 需要很好地理解業務 - 需要在理解業務之後識別業務子域。理解組織結構會有所幫助,因為組織是基於其能力構建的。

  • 需要高級別的領域模型 - 需要業務領域物件,因為它們對應於業務子域。

按絞殺者模式分解

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。當使用微服務架構構建大型複雜應用程式時,主要問題是如何設計鬆散耦合的微服務,或者如何將大型應用程式分解成小型鬆散耦合的服務?

解決方案

我們可以使用絞殺者模式定義微服務。絞殺者應用程式有兩種服務:

  • 現有行為 - 這些服務表現出先前存在於單體應用程式中的行為。

  • 新功能 - 這些服務實現新的行為。

因此,隨著時間的推移,微服務會增加,而單體應用程式會隨著功能從單體應用程式轉移到絞殺者應用程式而縮小。

示例

考慮一個線上書店的例子。最初,我們只開發了圖書目錄管理服務,而其他服務由遺留的單體應用程式支援。在開發過程中,越來越多的服務被開發出來,並且功能從單體應用程式中移走。

Decompose By Strangler Design Pattern

因此,當開發新服務時,單體應用程式會被絞殺,舊元件會被停用,新的微服務會被部署並支援新功能。絞殺者模式可以透過三個步驟實現:

  • 轉換 - 獨立開發微服務以實現單體應用程式的特定功能。

  • 共存 - 單體應用程式和微服務都將工作。使用者可以從兩個元件訪問功能。

  • 消除 - 一旦新開發的功能準備就緒,就從單體應用程式中移除該功能。

優點

  • 測試驅動開發 - 由於服務是分塊開發的,我們可以使用 TDD 進行業務邏輯並確保程式碼質量。

  • 獨立團隊 - 團隊可以並行地在單體應用程式和微服務上工作,從而形成強大的交付機制。

微服務設計模式 - API 閘道器

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。當使用微服務架構構建大型複雜應用程式時,微服務可以使用不同的協議。例如,一些微服務使用 REST,而另一些微服務遵循 AMQP。現在問題是如何允許客戶端無縫地訪問每個微服務,而無需擔心協議和其他複雜性。

解決方案

我們可以定義一個 API 閘道器,它將充當所有型別客戶端的單一入口點。以下是 API 閘道器的其他好處:

  • 簡單的代理 - API 閘道器可以充當某些請求的簡單代理,將它們重定向到相關服務。

  • 多個服務 - API 閘道器可以將呼叫重定向到多個服務。

  • 客戶端特定的 API - API 閘道器還可以提供客戶端特定的 API,例如,桌面版與移動應用程式的 API 不同。

  • 協議處理 - API 閘道器在內部處理每個服務呼叫的通訊協議,客戶端只需關注請求/響應。

  • 安全性和身份驗證 - API 閘道器可以實現一種安全機制,只有在身份驗證和授權後,每個請求才能到達服務。

示例

考慮一個線上書店的例子。API 閘道器允許在多個裝置上無縫地使用線上書店 API。

API Gateway Design Pattern

優點

  • 客戶端隔離 - 客戶端無需瞭解微服務的位置或如何呼叫它們。

  • 多個服務呼叫 - API 閘道器可以處理多個服務並給出一個結果,從而可以減少往返次數並提高效能。

  • 標準介面 - API 閘道器為客戶端提供標準介面以從微服務獲取響應。

微服務設計模式 - 聚合器

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。當使用微服務架構構建大型複雜應用程式時,我們經常需要獲取多個微服務的組合結果並在應用程式上顯示。

解決方案

我們可以定義一個聚合器 (Aggregator) 作為簡單的 Web 模組,它充當負載均衡器,這意味著它將根據需求呼叫不同的服務。下圖顯示了一個帶有聚合器設計的簡單微服務 Web 應用程式。如下圖所示,“聚合器”負責逐一呼叫不同的服務。如果我們需要對服務 A、B 和 C 的結果應用任何業務邏輯,那麼我們可以在聚合器本身中實現業務邏輯。

Aggregator Pattern

聚合器可以再次作為另一個服務暴露給外部世界,並在需要時被其他人使用。在開發聚合器模式 Web 服務時,我們需要記住我們的每個服務 A、B 和 C 都應該有自己的快取層,並且應該是全棧式的。

微服務設計模式 - 代理 (Proxy)

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。當使用微服務架構構建大型複雜應用程式時,我們經常需要準備一個統一的介面,可以在每次服務呼叫之前執行諸如身份驗證和授權之類的公共工作。

解決方案

代理微服務模式是聚合器模型的一種變體。在這個模型中,我們將使用代理模組而不是聚合模組。代理服務可以分別呼叫不同的服務。

Proxy Pattern

在代理模式中,我們可以透過提供一個啞代理層來構建一層額外的安全性。此層的作用類似於介面。

優點

  • 代理模式提供了一個統一的介面,而不是每個微服務不同的介面。

  • 代理模式允許在一個地方應用統一的關注點,例如日誌記錄、安全等。

客戶端 UI 組合

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。現在如何開發一個可以顯示來自多個服務資料的 UI 頁面/螢幕?

解決方案

每個 UI 團隊可以開發一個客戶端 UI 元件,例如 Angular 元件,它實現或對應於特定的微服務。對於多個服務,UI 團隊負責透過構建由多個特定服務 UI 元件組成的頁面來準備骨架 UI 或頁面骨架。

Client Side UI Composition Design Pattern

優點

  • 獨立的 UI 團隊 - 一旦微服務契約可用,每個 UI 團隊都可以工作,而無需所有微服務的可用性。

  • 可管理的 UI 開發 - 以元件形式開發的 UI 變得更易於管理和高效。

  • 更輕鬆的開發 - UI 開發變得更容易和更易於維護。

責任鏈 (Chain of Responsibilities)

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。如果一個服務需要另一個服務的輸出作為依賴項,那麼如何處理這種情況?

解決方案

我們可以使用責任鏈模式。顧名思義,這種組合模式將遵循鏈式結構。在這裡,我們不會在客戶端和服務層之間使用任何東西。相反,我們將允許客戶端直接與服務通訊,並且所有服務都將以一種方式連結起來,即一個服務的輸出將成為下一個服務的輸入。下圖顯示了一個典型的鏈式模式微服務。

Chain of Responsibilities Design Pattern

缺點

這種架構的一個主要缺點是,客戶端將被阻塞,直到整個過程完成。因此,強烈建議將鏈的長度保持儘可能短。

微服務設計模式 - 分支 (Branch)

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。現在考慮一種情況,一個服務需要另一個服務的輸出作為依賴項,並且客戶端可以呼叫任何服務。

解決方案

我們在這裡可以使用分支微服務設計模式。分支微服務模式是聚合器模式和鏈式模式的擴充套件版本。在這個設計模式中,客戶端可以直接與服務通訊。此外,一個服務可以同時與多個服務通訊。下圖是分支微服務的示意圖。

Branch Microservices Design Pattern

優點

分支微服務模式允許開發人員動態配置服務呼叫。所有服務呼叫都將併發發生,這意味著服務 A 可以同時呼叫服務 B 和 C。

每個服務一個數據庫

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。基於微服務的應用程式中資料庫的結構/架構應該是什麼?

解決方案

我們可以將每個微服務的資料保持為該微服務的私有資料,並且這些資料只能透過相關的微服務訪問。微服務將使用自己的資料庫進行事務處理。下圖顯示了每個服務設計模式的資料庫實現。

Database per Service Microservices Design Pattern

每個服務一個數據庫並不總是需要單獨配置資料庫。考慮到關係資料庫,我們可以透過以下方式實現該模式。

  • 每個服務的私有表 - 每個微服務都可以利用一組表,並且這些表只能透過其相關的微服務訪問。

  • 每個服務的模式 - 可以為每個微服務定義一個單獨的模式。

  • 每個服務的資料庫伺服器 - 可以為每個微服務配置整個資料庫伺服器。

服務共享資料庫

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。基於微服務的應用程式中資料庫的結構/架構應該是什麼?

解決方案

我們可以使用一個在微服務之間共享的資料庫。每個服務都可以自由地使用其他服務可以訪問的資料。資料庫將維護 ACID 事務。

Shared Database per Service Microservices Design Pattern

在這個模式中,每個服務都應該使用底層資料庫的事務管理,以便可以利用資料庫的 ACID 屬性。考慮以下虛擬碼:

BEGIN TRANSACTION
…
SELECT * FROM ORDERS WHERE CUSTOMER_ID = ?
…
SELECT CREDIT_LIMIT FROM CUSTOMERS WHERE CUSTOMER_ID = ?
…
INSERT INTO ORDERS ... WHERE ORDER_LIMIT < CREDIT_LIMIT
…
COMMIT TRANSACTION

這裡訂單服務使用資料庫事務來確保在訂購期間檢查客戶的信用額度。

命令查詢責任隔離 (CQRS)

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署;如果我們使用了每個服務一個數據庫的設計模式,那麼如何進行需要來自多個服務的資料的查詢?

解決方案

我們可以定義一個檢視資料庫,這是一個只讀資料,用於支援所需的查詢。應用程式將透過訂閱擁有資料服務的事件來保持檢視資料庫的最新狀態。在這個設計模式中,我們將更新和讀取操作分開。一個服務只讀取資料,其他服務更新資料。

Command Query Responsibility Segregator Pattern

為了實現這個模式,我們經常需要重構領域模型以支援查詢資料和更新資料的單獨操作,以便每個操作都可以由微服務獨立處理。CQRS 模式確保讀取資料的操作與更新資料的操作分開。因此,一個操作可以讀取或寫入資料,但不能同時執行兩者。

現在多個服務可以更新記錄並將事件傳送到應用程式以更新檢視資料庫。這有助於查詢服務獲取一致的資料,而不會影響效能。

微服務設計模式 - Saga

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署;如果我們使用了每個服務一個數據庫的設計模式,那麼如何實現跨越多個服務的事務?

解決方案

我們可以使用 Saga 模式。Saga 是一系列本地事務。在這個模式中,每個事務都會更新資料庫並觸發事件或釋出訊息以進行 Saga 中的下一個事務。如果任何本地事務失敗,Saga 將觸發一系列事務來撤消本地事務迄今為止所做的更改。

考慮訂單服務和客戶服務的示例。訂單服務可以下訂單,然後詢問客戶服務是否超過信用額度。如果信用額度超過,客戶服務將向訂單服務發出事件以取消訂單,否則成功下單。

Saga Pattern

為了實現這個模式,我們經常需要基於編排的 Saga 或基於協調器的 Saga。

在基於編排的 Saga 中,服務在本地事務期間處理領域事件,並完成事務或撤消事務;而在基於協調器的 Saga 中,協調器物件在本地事務期間處理事件,然後告訴協調器要執行哪個本地事務。

非同步訊息 (Asynchronous Messaging)

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。微服務處理來自客戶端的請求,並且經常需要與其他微服務通訊以完成請求。因此需要程序間通訊協議。

解決方案

我們可以使用非同步訊息模式進行服務間通訊,因為使用同步通訊會導致服務的緊密耦合,並且還要求客戶端和服務在請求期間都可用。

使用非同步訊息,服務可以透過在訊息通道上交換訊息來通訊。以下是非同步訊息通訊的一些不同方法。

  • 請求/同步響應 - 在此方法中,服務向另一個服務發出請求並立即期望回覆。

  • 通知 - 在此方法中,服務向接收者傳送訊息,但不期望任何響應。接收者也不期望傳送響應。

  • 請求/非同步響應 - 在此方法中,服務向另一個服務發出請求,並期望在合理的時間範圍內收到回覆。

  • 釋出/訂閱 - 在此方法中,服務向零個或多個接收者釋出訊息。訂閱該訊息的服務將收到相同的回覆。不需要響應。

  • 釋出/非同步響應 - 在此方法中,服務向零個或多個接收者釋出訊息。訂閱該訊息的服務將收到相同的回覆。其中一些會發送確認/回覆。

示例

RabbitMQ 和 Apache Kafka 是微服務領域非同步訊息傳遞的良好示例。

事件溯源

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署;如果我們使用了每個服務一個數據庫的設計模式,那麼如何實現跨越多個服務的事務?

解決方案

我們可以使用事件溯源模式進行服務間通訊。在這種型別的通訊中,每個服務都會為每次執行的操作將事件持久化到事件儲存中。每個服務都可以訂閱這些事件並相應地更新其事務狀態。考慮訂單服務與客戶服務的案例。客戶服務可以訂閱訂單服務更新的事件並相應地更新其狀態。

Event Sourcing Pattern

優點

以下是使用事件溯源模式的優點:

  • 非常適合事件驅動的架構 - 此模式允許在狀態更改時可靠地釋出事件。

  • 持久化事件 - 由於持久化的是事件而不是領域物件,因此不會出現物件關係不匹配的情況。

  • 審計日誌 - 由於每個更改都會捕獲事件,因此審計日誌涵蓋了 100% 的更改。

  • 實體狀態標識 - 我們可以在事件資料庫上建立時間查詢,以檢查實體在任何時間點的當前狀態。

  • 單體到微服務架構的遷移變得更容易 - 使用事件溯源模式,我們可以建立透過事件進行通訊的鬆散耦合的微服務。因此,從單體到基於微服務的應用程式開發的遷移變得更容易。

日誌聚合

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,從而實現持續交付/部署。請求通常跨越多個服務。每個服務例項都以標準化格式在其日誌檔案中寫入一些資訊。這些日誌可以是資訊、錯誤、警告或除錯日誌。如何使用這些日誌分析和排除應用程式問題?

解決方案

我們可以使用集中的日誌服務,它聚合來自每個服務的日誌。使用者應該能夠搜尋和分析此日誌服務提供的日誌。使用者應該能夠在日誌中出現特定型別的訊息時配置警報。

關聯 ID

當第一個微服務接收到呼叫時,它應該生成一個關聯 ID,然後可以將其傳遞給下游服務。此關聯 ID 應該記錄在所有微服務中。這將有助於跟蹤跨越多個服務的相關資訊。

可搜尋的日誌

由於日誌應放置在集中位置,因此下圖展示瞭如何使用 Kafka、LogStash 和 Kibana 來聚合日誌並使用所需的過濾器搜尋已索引的日誌。

Log Aggregation Pattern

微服務生成日誌,這些日誌使用 kafka 日誌追加器釋出,然後將日誌訊息輸出到 kafka 叢集。LogStash 從 kafka 中提取訊息,轉換訊息併發布到 Elasticsearch 容器。現在,Kibana 提供了一個視覺化介面來搜尋/讀取 Elasticsearch 容器中已索引的日誌,並提供所需的過濾器。

效能指標

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。如何分析和解決應用程式問題?如何跟蹤應用程式效能並檢查瓶頸?如何以最少的執行時開銷跟蹤多個服務?

解決方案

我們可以實現一個監控服務,負責收集有關各個操作的統計資料,以及一箇中央指標服務,該服務應聚合指標並提供報告和警報。這些服務可以透過兩種方式收集效能指標:

  • 推送 - 服務將指標推送到中央指標服務。

  • 拉取 - 中央指標服務從服務中拉取指標。

示例

以下是監控庫的示例:

以下是指標聚合庫的示例:

  • Prometheus - 一個開源系統監控和警報工具包。

  • AWS CloudWatch - AWS 資源和服務可觀察性和監控服務。

分散式追蹤

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。請求通常跨越多個服務。使用外部監控,我們可以檢查整體響應時間和呼叫次數,但是如何深入瞭解單個事務/操作?服務可以使用資料庫、訊息佇列、事件溯源等。如何跟蹤跨越多個服務的散佈日誌?

解決方案

我們可以監控一個設計用於執行以下操作的服務:

  • 關聯 ID - 為每個外部請求生成唯一的外部請求 ID,並將此外部 ID 傳遞給處理請求的每個服務。

  • 記錄關聯 ID - 處理服務生成的每個日誌訊息都應具有此關聯 ID。

  • 記錄詳細資訊 - 當服務處理請求時,在日誌中記錄開始/結束時間和其他相關詳細資訊。

可搜尋的日誌

由於日誌應放置在集中位置,因此下圖展示瞭如何使用 Kafka、LogStash 和 Kibana 來聚合日誌並使用所需的過濾器搜尋已索引的日誌。

Log Aggregator Pattern

微服務生成日誌,這些日誌使用 kafka 日誌追加器釋出,然後將日誌訊息輸出到 kafka 叢集。LogStash 從 kafka 中提取訊息,轉換訊息併發布到 Elasticsearch 容器。現在,Kibana 提供了一個視覺化介面來搜尋/讀取 Elasticsearch 容器中已索引的日誌,並提供所需的過濾器。

微服務設計模式 - 健康檢查

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。現在,如果資料庫宕機或無法承受更多連線,則監控系統應發出警報。負載均衡器/服務登錄檔/API 閘道器不應將任何請求重定向到此類失敗的服務例項。因此,我們需要檢測正在執行的服務例項是否能夠接收請求。

解決方案

我們可以為每個服務新增一個健康檢查點,例如 HTTP /health,它返回服務健康狀態。此端點可以執行以下任務來檢查服務健康狀況:

  • 連線可用性 - 當前服務使用的資料庫連線或基礎設施服務的連線狀態。

  • 主機狀態 - 主機的狀態,例如磁碟空間、CPU 使用率、記憶體使用率等。

  • 特定於應用程式的邏輯 - 確定服務可用性的業務邏輯。

現在,監控服務(例如負載均衡器、服務登錄檔)定期呼叫健康檢查端點以檢查服務例項的健康狀況。

外部配置

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。這些服務通常與基礎設施服務或第三方服務互動。

基礎設施服務可能包括服務登錄檔、訊息代理、資料庫伺服器。第三方服務可以是支付服務、電子郵件服務、訊息服務。除了不同的服務之外,環境也經常不同。考慮以下情況:

  • 配置資料 - 應向微服務提供外部/第三方服務的配置,例如資料庫憑據、網路 URL 等。

  • 多個環境 - 通常存在不同的環境,例如開發、測試、預釋出或預生產和生產環境。服務應部署在每個環境中,而無需任何程式碼修改。

  • 不同的配置資料 - 外部/第三方服務的配置從開發到生產環境也會有所不同,例如開發資料庫到生產資料庫、測試支付處理器與原始支付處理器服務。

解決方案

我們可以將所有配置從資料庫憑據到網路 URL 外部化。服務將在啟動時讀取配置資料,例如從屬性檔案/系統環境變數或使用命令列引數。此模式有助於部署微服務,無需任何修改/重新編譯。

服務發現

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。這些服務通常在容器化/虛擬環境中執行,它們的例項數量和位置會動態變化。

因此,我們需要一種機制來使微服務的客戶端能夠向動態變化的服務例項發出請求。

解決方案

我們可以使用服務發現模式。要實現此模式,我們需要在特定固定位置執行路由器/負載均衡器,以及所有微服務例項都註冊的服務登錄檔。

現在,客戶端發出服務請求,它將到達負載均衡器,然後負載均衡器查詢服務登錄檔。如果服務例項可用,則請求將重定向到可用的服務例項。

Service Discovery Pattern

微服務設計模式 - 斷路器

問題陳述

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都可以以敏捷的方式獨立開發,以實現持續交付/部署。這些服務經常與其他微服務互動。現在,服務超載或不可用的可能性始終存在。在這種情況下,呼叫服務也將等待。如果多個服務被阻塞,則會影響效能,並可能對整個應用程式產生級聯影響。

現在,如何防止服務故障或網路故障級聯到其他服務?如果一項服務宕機,則不應向其發出更多請求。

解決方案

我們可以使用斷路器模式,其中代理服務充當斷路器。每個服務都應透過代理服務呼叫。代理服務維護超時和故障計數。如果連續故障超過閾值故障計數,則代理服務將跳閘斷路器並啟動超時時間段。在此超時時間段內,所有請求都將失敗。一旦此超時時間段結束,代理服務允許一定數量的測試請求傳遞到提供者服務。如果請求成功,代理服務將恢復操作;否則,它將再次跳閘斷路器並啟動超時時間段,在此期間將不接受任何請求。

藍綠部署

微服務架構將應用程式構建為一組鬆散耦合的微服務,每個服務都應以敏捷的方式獨立開發,以實現持續交付/部署。當要使用微服務架構構建大型複雜應用程式時,主要問題是如何設計鬆散耦合的微服務,或者如何在保持系統處於生產狀態的同時,將大型應用程式分解成小型鬆散耦合的服務。

解決方案

我們可以使用藍綠部署來定義部署新開發的微服務。在此模型中,使用者流量會逐漸從舊應用程式轉移到新的微服務應用程式。一旦微服務在生產環境中可用,負載均衡器就會將針對舊應用程式的請求重定向到新的微服務。

  • 藍色環境 - 在生產環境中執行的舊應用程式稱為藍色環境。

  • 綠色環境 - 部署的新服務複製了舊應用程式的給定部分,稱為綠色環境。

因此,隨著時間的推移,微服務會增加,而整體應用會隨著功能從整體應用遷移到微服務應用程式而縮小。

示例

考慮一個線上書店的例子。最初,我們只開發了圖書目錄管理服務,其他服務由遺留整體式應用程式支援。在開發過程中,越來越多的服務被開發出來,並且功能從整體應用中移出。

Blue Green Deployment Design Pattern

這種部署模式有助於減少停機時間,甚至在從整體式應用程式遷移到基於微服務的應用程式時實現零停機時間。

廣告