容器化的微服務

提示

本內容節錄自《Enterprise Application Patterns Using .NET MAUI》電子書,可以從 .NET Docs 取得,也可以免費下載 PDF 離線閱讀。

Enterprise Application Patterns Using .NET MAUI eBook cover thumbnail.

開發用戶端伺服器應用程式已導致著重於建置階層式應用程式,以在每個層級使用特定技術。 此類應用程式通常稱為「整合型」,並封裝在預先調整為尖峰負載的硬體上。 此開發方法的主要缺點是每個層級中的元件之間緊密結合,因此無法輕易調整個別元件;另外測試的成本也是缺點。 簡單更新可能會對層的其餘部分造成無法預期的影響,因此對應用程式元件進行變更需要重新測試並重新部署整個層。

特別要留意的是,在雲端的存留期中,無法輕易調整個別元件。 整合型應用程式包含網域特定功能,通常分成功能層,例如前端、商務邏輯與資料儲存體。 下圖說明整合型應用程式是藉由將整個應用程式複製到多部電腦來調整。

Monolithic application scaling approach.

微服務

微服務提供不同的應用程式開發與部署方法,這是一種適合現代化雲端應用程式靈活度、規模與可靠性需求的方法。 微服務應用程式分成獨立元件,可一起運作以提供應用程式的整體功能。 微服務一詞強調應用程式應該由小到足以反映特定考量的服務所組成,因此每個微服務都會實作單一函式。 此外,每個微服務都有定義完善的合約,其他微服務會與其通訊及共用資料。 微服務的一般範例包括購物車、庫存處理、購買子系統,以及付款處理。

相較於一起調整的大型整合型應用程式,微服務可以獨立調整。 這表示可以調整需要更多處理能力或網路頻寬以支援需求的特定功能區域,而不是對其他應用區域執行不必要的擴增。 下圖說明此方法,其中微服務會獨立部署及調整,以跨電腦建立服務的執行個體。

Microservices application scaling approach.

微服務擴增幾乎可以立即完成,讓應用程式能夠適應變更的負載。 例如,應用程式 Web 面向功能中的單一微服務可能是唯一需要擴增以處理其他傳入流量的微服務。

應用程式可擴縮性的傳統模型是具有負載平衡的無狀態層,且具有共用外部資料存放區以儲存持續性資料。 具狀態微服務會管理自己的永續性資料,通常會將其儲存於放置自身的伺服器上,以避免網路存取的額外負荷,以及跨服務作業的複雜度。 這可讓資料的處理速度最快,且可消除快取系統的需求。 此外,可調整的具狀態微服務通常會分割其執行個體之間的資料,以便管理資料大小,並傳輸超出單一伺服器可支援的輸送量。

微服務也支援獨立更新。 微服務之間的這種鬆散結合可提供快速且可靠的應用程式演進。 其獨立的分散式本質可協助回復更新,其中只有單一微服務的執行個體子集會隨時更新。 因此,若偵測到問題,可以在所有執行個體更新錯誤碼或組態之前復原有 Bug 的更新。 同樣地,微服務通常會使用結構描述版本設定,讓用戶端在套用更新時,不論要與哪個微服務執行個體進行通訊,都會看到一致的版本。

因此,微服務應用程式對於整合型應用程式有許多優點:

  • 每個微服務相對較小,因此管理及發展都很容易。
  • 每個微服務都可獨立部署及更新,而不影響其他服務。
  • 每個微服務都可以獨立擴增。 例如,目錄服務或購物籃服務可能需要擴增得比訂購服務多。 因此,擴增時,產生的基礎結構將更有效率地取用資源。
  • 每個微服務都會隔離任何問題。 例如,若某個服務中有問題,問題只會影響該服務。 其他服務可以繼續處理要求。
  • 每個微服務都可以使用最新技術。 因為微服務是自主且並存執行,所以可以使用最新的技術與架構,而不是強制使用整合型應用程式可能使用的舊版架構。

然而,微服務型解決方案也有潛在的缺點:

  • 選擇如何將應用程式分割成微服務可能很困難,因為每個微服務都必須完全自主、端對端,包括對其資料來源的責任。
  • 開發人員必須實作服務間通訊,這會增加應用程式的複雜度與延遲。
  • 多個微服務之間不可部分完成的交易通常不可行。 因此,商務需求必須在微服務之間採用最終一致性。
  • 在生產環境中,部署及管理許多獨立服務遭入侵的系統具有作業複雜度。
  • 直接用戶端對微服務通訊可能會使重構微服務的合約變得困難。 例如,經過一段時間後,系統分割成服務的方式可能需要變更。 單一服務可能會分割成兩個或多個服務,而兩個服務可能會合併。 當用戶端直接與微服務通訊時,此重構作業可能會中斷與用戶端應用程式的相容性。

貨櫃化

容器化是軟體開發的方法,其中會將應用程式及其版本設定相依性集合,以及其抽象化為部署資訊清單檔案的環境組態封裝為容器映像、測試為單位,並部署至主機作業系統。

容器是隔離、資源控制的可攜式作業環境,應用程式可以在不觸碰其他容器或主機資源的情況下執行。 因此,容器的外觀與行為會如同新安裝的實體電腦或虛擬機器。

容器與虛擬機器之間有許多相似之處,如下所示。

Comparison of virtual machines and containers.

容器可像實體或虛擬機器一樣執行作業系統、具有檔案系統,且可透過網路來存取。 然而,容器所使用的技術與概念還是與虛擬機器非常不同。 虛擬機器包含應用程式、必要的相依性,以及完整的客體作業系統。 容器包含應用程式及其相依性,但與其他容器共用作業系統,在主機作業系統上以獨立的處理序執行 (除了每個容器在特殊虛擬機器中執行的 Hyper-V 容器之外)。 因此,容器會共用資源,且通常需要比虛擬機器更少的資源。

容器導向開發與部署方法的優點是,其會消除大部分因環境設定不一致而發生的問題,以及其隨附的問題。 此外,容器會視需要將新的容器執行個體化,以允許快速的應用程式擴大功能。

建立及使用容器時的重要概念為:

概念 描述
容器主機 設定為裝載容器的實體或虛擬機器。 容器主機將會執行一或多個容器。
容器映像 映像是由堆疊在彼此之上的分層檔案系統聯集所組成,且為容器的基礎。 映像沒有狀態,且在部署至不同環境時一律不會變更。
容器 容器是映像的執行階段執行個體。
容器 OS 映像 容器會從映像進行部署。 在可能構成容器的眾多映像層中,容器作業系統映像是第一層。 容器作業系統不可變,而且無法修改。
容器存放庫 每當建立容器映像時,容器映像與其相依性即會儲存於本機存放庫中。 這些映像可在容器主機上重複使用多次。 容器映像也可以儲存於公用或私人登錄中 (例如 Docker Hub),以便在許多不同的容器主機之間使用。

企業在實作微服務型應用程式時逐漸採用容器,而 Docker 已成為受到大部分軟體平台與雲端廠商所採用的標準容器實作。

eShopOnContainers 參考應用程式會使用 Docker 裝載四個容器化後端微服務,如下圖所示。

eShopOnContainers reference application back-end microservices.

參考應用程式中後端服務的架構會以共同作業微服務與容器的形式分解成多個自主子系統。 每個微服務都提供單一功能區域:身分識別服務、目錄服務、訂購服務,以及購物籃服務。

每個微服務都有自己的資料庫,因此可與其他微服務完全分離。 必要時,會使用應用程式層級事件來達成不同微服務資料庫之間的一致性。 如需詳細資訊,請參閱微服務之間的通訊

如需參考應用程式的詳細資訊,請參閱 .NET 微服務:容器化 .NET 應用程式的架構

用戶端與微服務之間的通訊

eShopOnContainers 多平台應用程式會使用「直接用戶端對微服務」通訊來與容器化後端微服務通訊,如下所示。

Direct client-to-microservice communication.

有了直接用戶端對微服務通訊,多平台應用程式會在每個微服務都有不同 TCP 連接埠的情況下,透過其公用端點直接對每個微服務提出要求。 在生產環境中,端點通常會對應至微服務的負載平衡器,這會在可用的微服務執行個體之間散發要求。

提示

請考慮使用 API 閘道通訊。

建置大型且複雜的微服務型應用程式時,直接用戶端對微服務通訊可能會有缺點,但對小型應用程式而言很夠用了。 使用數十個微服務設計大型微服務型應用程式時,請考慮使用 API 閘道通訊。 如需詳細資訊,請參閱 .NET 微服務:容器化 .NET 應用程式的架構

微服務之間的通訊

微服務型應用程式是分散式系統,可能會在多部電腦上執行。 每個服務執行個體通常就是一個處理序。 因此,服務必須使用處理序間的通訊協定 (例如 HTTP、TCP、進階訊息佇列通訊協定 (AMQP) 或二進位通訊協定,根據每個服務的本質) 來互動。

微服務對微服務通訊的兩個常見方法,一個是在查詢資料時以 HTTP 為基礎的 REST 通訊,另一個是跨多個微服務通訊更新時的輕量型非同步傳訊。

在跨多個微服務傳播變更時,非同步傳訊型事件驅動通訊非常重要。 透過此方法,微服務會在發生值得注意的情況時發行事件;例如,當其更新商務實體時。 其他微服務會訂閱這些事件。 然後,當微服務收到事件時,其可更新自己的商務實體,這可能會導致發行更多的事件。 此發行-訂閱功能通常是透過事件匯流排來達成。

事件匯流排允許微服務之間的發行-訂閱通訊,而不需要元件來明確知道彼此,如下所示。

Publish-subscribe with an event bus.

從應用程式的觀點來看,事件匯流排只是一個透過介面公開的發行-訂閱通道。 然而,實作事件匯流排的方式可能會有所不同。 例如,事件匯流排實作可以使用 RabbitMQ、Azure 服務匯流排或其他服務匯流排,例如 NServiceBus 與 MassTransit。 下圖顯示 eShopOnContainers 參考應用程式中使用事件匯流排的方式。

Asynchronous event-driven communication in the reference application.

使用 RabbitMQ 實作的 eShopOnContainers 事件匯流排提供一對多非同步發行-訂閱功能。 這表示在發行事件之後,可以有多個訂閱者接聽相同的事件。 下圖說明此關聯性。

One-to-many communication

此一對多通訊方法會使用事件實作跨越多個服務的商務交易,以確保服務之間的最終一致性。 最終一致的交易是由一系列的分散式步驟所組成。 因此,當使用者設定檔微服務收到 UpdateUser 命令時,它會更新其資料庫中的使用者詳細資料,並將 UserUpdated 事件發行至事件匯流排。 購物籃微服務與訂購微服務都已訂閱接收此事件,並在各自的資料庫中更新其購買者資訊。

注意

使用 RabbitMQ 實作的 eShopOnContainers 事件匯流排僅供概念證明使用。 針對生產環境系統,應該考慮替代事件匯流排實作。

如需事件匯流排實作的詳細資訊,請參閱 .NET 微服務:容器化 .NET 應用程式的架構

摘要

微服務提供應用程式開發與部署的方法,這是一種適合現代化雲端應用程式靈活度、規模與可靠性需求的方法。 微服務的主要優點之一是可以獨立擴增,這表示可以調整需要更多處理能力或網路頻寬的特定功能區域來支援需求,而不需要對未遇到增加需求的應用程式區域執行不必要的調整。

容器是隔離、資源控制的可攜式作業環境,其中應用程式可以在不觸碰其他容器或主機之資源的情況下執行。 企業在實作微服務型應用程式時逐漸採用容器,而 Docker 已成為大部分軟體平台與雲端廠商採用的標準容器實作。