共用方式為


API 閘道模式與直接用戶端對微服務通訊

小提示

此內容是適用於容器化 .NET 應用程式的電子書.NET 微服務架構摘錄,可在 .NET Docs 或免費下載的 PDF 中取得,可脫機讀取。

.NET 微服務架構的容器化 .NET 應用程式電子書封面縮圖。

在微服務架構中,每個微服務都會公開一組(通常是)細部端點。 此事實可能會影響用戶端對微服務的通訊,如本節所述。

直接用戶端對微服務通訊

可能的方法是使用直接用戶端對微服務通訊架構。 在此方法中,用戶端應用程式可以直接對部分微服務提出要求,如圖 4-12 所示。

顯示用戶端對微服務通訊架構的圖表。

圖 4-12。 使用直接用戶端對微服務通訊架構

在此方法中,每個微服務都有公用端點,有時每個微服務都有不同的 TCP 連接埠。 特定服務的 URL 範例可能是 Azure 中的下列 URL:

http://eshoponcontainers.westus.cloudapp.azure.com:88/

在以叢集為基礎的生產環境中,該 URL 會對應至叢集中所使用的負載平衡器,進而將要求分散到微服務。 在生產環境中,您可以在微服務與因特網之間有應用程式傳遞控制器(ADC),例如 Azure 應用程式閘道 。 此層可作為透明層,不僅會執行負載平衡,還能藉由提供SSL終止來保護您的服務。 此方法透過將 CPU 密集型的 SSL 終止及其他路由職責轉移至 Azure 應用程式閘道,以改善主機的負載。 在任何情況下,從邏輯應用程式架構的觀點來看,負載平衡器和 ADC 都是透明的。

直接用戶端對微服務通訊架構對於小型微服務型應用程式而言可能足夠好,特別是當用戶端應用程式是像是 ASP.NET MVC 應用程式的伺服器端 Web 應用程式時。 不過,當您建置大型和複雜的微服務型應用程式時(例如,處理數十種微服務類型時),特別是當用戶端應用程式是遠端行動應用程式或 SPA Web 應用程式時,這種方法會面臨一些問題。

根據微服務開發大型應用程式時,請考慮下列問題:

  • 用戶端應用程式如何將後端的要求數目降到最低,並減少對多個微服務的閒聊通訊?

與多個微服務互動以建置單一UI畫面會增加因特網往返次數。 這種方法會增加UI端的延遲和複雜度。 在理想情況下,回應應該在伺服器端有效率地匯總。 此方法可減少延遲,因為多個數據片段會以平行方式返回,而某些 UI 可以在數據就緒后立即顯示數據。

  • 如何處理跨領域考慮,例如授權、數據轉換和動態要求分派?

在每個微服務上實作例如安全性和授權等跨領域考慮,可能需要大量開發工作。 可能的方法是讓 Docker 主機或內部叢集內的這些服務限制從外部直接存取這些服務,並在集中式位置實作這些跨領域考慮,例如 API 閘道。

  • 客戶端應用程式如何與使用非網際網路友好協定的服務進行通訊?

用戶端應用程式不支援伺服器端使用的通訊協定(例如 AMQP 或二進位通訊協定)。 因此,要求必須透過 HTTP/HTTPS 等通訊協定執行,之後轉譯為其他通訊協定。 在這種情況下,中間人攻擊 方法可以提供幫助。

  • 如何塑造專為行動應用程式打造的外觀?

多個微服務的 API 可能無法針對不同用戶端應用程式的需求進行妥善設計。 例如,行動應用程式的需求可能與 Web 應用程式的需求不同。 針對行動應用程式,您可能需要進一步優化,以便數據回應更有效率。 您可以藉由匯總來自多個微服務的數據並傳回單一數據集,有時消除行動應用程式不需要回應中的任何數據,來執行這項功能。 當然,您可能會壓縮該數據。 同樣地,行動應用程式與微服務之間的介面或 API 對於此案例來說,是很便利的。

為何考慮 API 閘道,而不是直接用戶端對微服務通訊

在微服務架構中,用戶端應用程式通常需要從多個微服務取用功能。 如果直接進行該消耗操作,客戶端必須處理多次與微服務端點的通訊。 當應用程式演進和引進新的微服務或更新現有的微服務時,會發生什麼事? 如果您的應用程式有許多微服務,處理用戶端應用程式中的許多端點可能是噩夢。 由於用戶端應用程式會與這些內部端點結合,因此未來演進微服務可能會對用戶端應用程式造成高影響。

因此,具有中繼層級或間接存取層(網關)對於微服務型應用程式來說,相當方便。 如果您沒有 API 閘道,用戶端應用程式必須將要求直接傳送至微服務,並引發問題,例如下列問題:

  • 結合:如果沒有 API 閘道模式,用戶端應用程式會與內部微服務結合。 用戶端應用程式必須知道如何在微服務中分解應用程式的多個區域。 在演進和重構內部微服務時,這些動作會影響維護,因為它們會因為用戶端應用程式直接參考內部微服務而造成用戶端應用程式的重大變更。 用戶端應用程式需要經常更新,讓解決方案更難演進。

  • 來回行程太多:用戶端應用程式中的單一頁面/畫面可能需要多次呼叫多個服務。 這種方法可能會導致客戶端與伺服器之間的多個網路來回行程,進而增加顯著的延遲。 在中繼層級中處理的匯總可以改善用戶端應用程式的效能和用戶體驗。

  • 安全性問題:如果沒有閘道,所有微服務都必須公開至「外部世界」,使受攻擊面大於如果您隱藏用戶端應用程式未直接使用的內部微服務。 受攻擊面越小,您的應用程式就越安全。

  • 跨領域考慮:每個公開發佈的微服務都必須處理授權和 SSL 等考慮。 在許多情況下,這些考慮可以在單一層中處理,以便簡化內部微服務。

什麼是 API 閘道模式?

當您使用多個用戶端應用程式來設計和建置大型或複雜的微服務型應用程式時,請考慮的不錯方法是 API 閘道。 此模式是一項服務,可為特定微服務群組提供單一進入點。 這類似於面向對象設計的 Facade模式 ,但在此情況下,它是分散式系統的一部分。 API 閘道器模式有時也稱為「前端的後端」(BFF),因為建置時考慮了用戶端應用程式的需求。

因此,API 閘道位於用戶端應用程式與微服務之間。 其可作為反向 Proxy,將要求從用戶端路由傳送至服務。 它也可以提供其他跨領域功能,例如驗證、SSL 終止和快取。

圖 4-13 顯示如何將自定義 API 閘道融入僅有少數微服務的簡化微服務架構中。

此圖顯示實作為自定義服務的 API 閘道。

圖 4-13。 使用作為自訂服務實作的 API 閘道

應用程式會連線到單一端點 API 閘道,其設定為將要求轉送至個別微服務。 在此範例中,API 閘道會實作為以容器身分執行的自定義 ASP.NET Core WebHost 服務。

請務必強調在該圖表中,您會使用一個面向多個不同用戶端應用程式的單一自定義 API 閘道服務。 這一事實可能是重要的風險,因為您的 API 閘道服務將會根據用戶端應用程式的許多不同需求而成長和演進。 最後,由於這些不同的需求,因此會膨脹,而且實際上它可能類似於整合型應用程式或整合型服務。 這就是為什麼強烈建議在多個服務或多個較小的 API 閘道中分割 API 閘道,例如,每個用戶端應用程式的一種尺寸類型。

實作 API 閘道模式時,您必須小心。 通常,讓單一 API 閘道匯總您應用程式的所有內部微服務並不是個好主意。 如果這樣做,它會做為整合型匯總工具或協調器,並藉由結合所有微服務來違反微服務自主性。

因此,API 閘道應該根據商業界限和用戶端應用程式進行隔離,而不是作為所有內部微服務的單一匯總工具。

將 API 閘道層級拆分為多個 API 閘道時,如果您的應用程式擁有多個用戶端應用程式,這可以作為識別多個 API 閘道類型的主要考量,從而為每個用戶端應用程式的需求量身打造不同的外觀。 此案例是名為「前端後端」(BFF)的模式,其中每個 API 閘道都可以針對每個用戶端應用程式類型提供不同的 API,甚至可能藉由實作呼叫多個內部微服務之下的特定配接器程式代碼來根據用戶端規格提供不同的 API,如下圖所示:

顯示多個自定義 API 閘道的圖表。

圖 4-13.1。 使用多個自定義 API 閘道

圖 4-13.1 顯示依用戶端類型隔離的 API 閘道;一個用於行動用戶端,另一個用於 Web 用戶端。 傳統 Web 應用程式會連線到使用 Web API 閘道的 MVC 微服務。 此範例描述具有多個精細 API 閘道的簡化架構。 在此情況下,針對每個 API 閘道所識別的界限純粹是以「前端的後端」(BFF) 模式為基礎,因此僅根據每個用戶端應用程式所需的 API。 但在較大的應用程式中,您也應該進一步根據商業界限建立其他 API 閘道,作為第二個設計樞紐。

API 閘道模式的主要功能

API 閘道可以提供多個功能。 視產品而定,它可能會提供更豐富或更簡單的功能,不過,任何 API 閘道最重要的基本功能都是下列設計模式:

反向代理或閘道路由。 API 閘道提供反向代理,將請求重新導向或路由至內部微服務的端點(第 7 層路由,通常為 HTTP 請求)。 閘道會為用戶端應用程式提供單一端點或 URL,然後在內部將要求對應至一組內部微服務。 此路由功能有助於將用戶端應用程式和微服務分離,同時在將單體式 API 現代化時非常便捷。透過將 API 閘道定位於單體式 API 和用戶端應用程式之間,您可以在仍使用舊有的單體式 API 的同時,將新 API 加入為新的微服務,直至未來將單體式 API 拆分為多個微服務。 由於 API 閘道,用戶端應用程式不會注意到所使用的 API 是否實作為內部微服務或整合型 API,更重要的是,隨著 API 閘道路由的演進和重構至微服務,用戶端應用程式不會受到任何 URI 變更的影響。

如需詳細資訊,請參閱 網關路由模式

要求匯總。 作為閘道模式的一部分,您可以將多個用戶端要求(通常是 HTTP 要求)匯總成單一用戶端要求,以多個內部微服務為目標。 當用戶端頁面/畫面需要數個微服務的資訊時,此模式特別方便。 使用這種方法,用戶端應用程式會將單一要求傳送至 API 閘道,以將數個要求分派至內部微服務,然後匯總結果,並將所有專案傳回用戶端應用程式。 此設計模式的主要優點和目標是減少用戶端應用程式與後端 API 之間的閒聊,這對微服務所在的數據中心外遠端應用程式特別重要,例如行動應用程式或來自用戶端遠端瀏覽器中 JavaScript 的 SPA 應用程式要求。 對於在伺服器環境中執行要求的一般 Web 應用程式(例如 ASP.NET Core MVC Web 應用程式),此模式並不那麼重要,因為延遲比遠端用戶端應用程式小得多。

視您使用的 API 閘道產品而定,它可能會執行此匯總。 不過,在許多情況下,在 API 閘道的範圍內建立匯總微服務更有彈性,因此您會在程式代碼中定義匯總(也就是 C# 程式代碼):

如需詳細資訊,請參閱 網關匯總模式

跨領域考慮或閘道卸除。 根據每個 API 閘道產品所提供的功能,您可以將功能從個別微服務卸除至閘道,藉由將跨領域考慮合併成一層來簡化每個微服務的實作。 這種方法特別方便用於能在各個內部微服務中正確實作的專門功能,例如下列功能:

  • 身份驗證與授權
  • 服務探索整合
  • 回應快取處理
  • 重試原則、斷路器和 QoS
  • 速率限制和節流
  • 負載平衡
  • 記錄、追蹤、相互關聯
  • 標頭、查詢字串和宣告轉換
  • IP 允許清單

如需詳細資訊,請參閱 網關卸除模式

使用具有 API 閘道功能的產品

根據每個實作而定,API 閘道產品可能會提供更多跨領域考慮。 我們將在這裡探索:

Azure API 管理

Azure API 管理 (如圖 4-14 所示)不僅解決了 API 閘道的需求,還能提供從 API 收集深入解析等功能。 如果您使用 API 管理解決方案,API 閘道只是該完整 API 管理解決方案內的元件。

顯示如何使用 Azure API 管理作為 API 閘道的圖表。

圖 4-14。 針對 API 閘道使用 Azure API 管理

Azure API 管理可解決您的 API 閘道和管理需求,例如記錄、安全性、計量等。在此情況下,使用 Azure API 管理之類的產品時,您可能會有單一 API 閘道的風險並不高,因為這類 API 閘道會「更精簡」,這表示您不會實作可能演變成整合型元件的自定義 C# 程式代碼。

API 閘道產品通常就像入口通訊的反向代理,在這單一層中,您可以篩選內部微服務的 API,並將授權套用至已發佈的 API。

API 管理系統提供的深入解析可協助您瞭解 API 的使用方式,以及其執行方式。 它們可藉由讓您檢視近乎即時的分析報告,以及識別可能影響您企業的趨勢,來執行這項活動。 此外,您可以有關於要求和響應活動的記錄,以進行進一步的在線和離線分析。

透過 Azure API 管理,您可以使用金鑰、令牌和 IP 篩選來保護 API。 這些功能可讓您強制執行彈性且精細的配額和速率限制、使用原則修改 API 的形狀和行為,以及使用回應快取來改善效能。

在本指南和參考範例應用程式 (eShopOnContainers)中,此架構僅限於更簡單且自定義的容器化架構,以專注於一般容器,而不需要使用 Azure API 管理之類的 PaaS 產品。 但對於部署至 Microsoft Azure 的大型微服務型應用程式,建議您評估 Azure API 管理作為生產環境中 API 閘道的基礎。

豹貓

Ocelot 是輕量型 API 閘道,建議使用更簡單的方法。 Ocelot 是開放原始碼 .NET Core 型 API 閘道,特別針對需要統一進入其系統的微服務架構所建立。 它是輕量、快速且具擴充性的,並提供路由和驗證等多種功能。

eShopOnContainers 參考應用程式 2.0 選擇 Ocelot 的主要原因,是因為 Ocelot 是 .NET Core 輕量型 API 閘道,您可以部署到您要部署微服務/容器的相同應用程式部署環境,例如 Docker 主機、Kubernetes 等。由於它是以 .NET Core 為基礎,因此其跨平臺可讓您在Linux或 Windows 上部署。

先前的圖示展示了以容器運行的自定義 API 閘道,這正是您如何在容器中運行 Ocelot,以及如何在微服務型應用程式中使用。

此外,市場上有許多其他產品提供 API Gateway 功能,例如 Apigee、Kong、MuleSoft、WSO2 和其他產品,如 Linkerd 和 Istio,用於服務網格入口控制器功能。

在初始架構和模式說明小節之後,下一節將說明如何使用 Ocelot 實作 API 閘道。

API 閘道模式的缺點

  • 最重要的缺點是,當您實作 API 閘道時,您會結合該層與內部微服務。 這樣的結合可能會為您的應用程式帶來嚴重的困難。 Azure 服務總線小組的 Clemens Vaster 將這一潛在困難稱為 GOTO 2016 的「傳訊和微服務」研討會中的「新 ESB」。

  • 使用微服務 API 閘道會建立額外的可能單一失敗點。

  • API 閘道可能會因為額外的網路呼叫而增加回應時間。 不過,此額外呼叫的影響通常不及讓用戶端介面冗頻地直接呼叫微服務內部。

  • 如果未正確擴展或分散,API 閘道可能會成為瓶頸。

  • 如果 API 閘道包含自訂邏輯和資料匯總,則需要額外的開發成本和未來的維護。 開發人員必須更新 API 閘道,才能公開每個微服務的端點。 此外,內部微服務中的實作變更可能會導致 API 閘道層級的程式代碼變更。 不過,如果 API 閘道只是套用安全性、記錄和版本設定(如同使用 Azure API 管理時),則可能不會套用額外的開發成本。

  • 如果 API 閘道是由單一小組所開發,可能會有開發瓶頸。 此層面是選擇較佳方法的另一個原因,即使用數個能夠回應不同用戶端需求的細緻 API 閘道。 您也可以將 API Gateway 內部區隔成由各小組負責的多個區域或層級,進行內部微服務的管理和運作。

其他資源