微服務從設計到部署(二)使用 API 網關

来源:http://www.cnblogs.com/oopsguy/archive/2017/08/31/7456592.html
-Advertisement-
Play Games

當您選擇將應用程式構建成為一組微服務時,您需要決定應用程式客戶端將如何與微服務進行交互。單體應用程式只有一組端點(endpoint),通常使用複製(replicated)結合負載均衡來分配流量。然而,在微服務架構中,每個微服務都暴露一組通常比較細顆粒的端點。在本文中,我們將研究如何改進客戶端通信,並... ...


鏈接https://github.com/oopsguy/microservices-from-design-to-deployment-chinese
譯者Oopsguy

本書的七個章節是關於設計、構建和部署微服務。第一章介紹了微服務架構模式。它闡述使用微服務的優點與缺點,以及儘管如此,微服務通常是複雜應用的理想選擇。該系列的第二篇文章將探討使用 API 網關構建微服務。

當您選擇將應用程式構建成為一組微服務時,您需要決定應用程式客戶端將如何與微服務進行交互。單體應用程式只有一組端點(endpoint),通常使用複製(replicated)結合負載均衡來分配流量。

然而,在微服務架構中,每個微服務都暴露一組通常比較細顆粒的端點。在本文中,我們將研究如何改進客戶端通信,並提出一個使用 API 網關的方案。

2.1、簡介

我們假設您正在為一個購物應用開發一個本地(native)移動客戶端。您可能需要實現一個產品詳細信息頁面,用於展示給定商品的信息。

例如,圖 2-1 展示了在 Amazon 的 Android 移動應用中的滾動產品信息時所看的內容。

圖 2-1、一個簡單的購物應用

即使這是一個智能手機應用,產品詳細信息頁面展示了很多信息。例如,不僅有基本的產品信息,如名稱、描述和價格,頁面還展示了:

  1. 購物車中的物品數量
  2. 訂單歷史
  3. 客戶評論
  4. 低庫存警告
  5. 配送選項
  6. 各種推薦,包括了買了此產品的客戶經常買的其他產品
  7. 選擇性購買選項

在使用單體應用架構的情況下,移動客戶端通過對應用程式進行單個 REST 調用來檢索此數據,例如:

GET api.company.com/productdetails/productId

負載均衡器將請求路由到幾個相同應用程式實例中的其中一個。之後,應用程式查詢各個資料庫表並返迴響應給客戶端。相比之下,當使用微服務架構時,產品詳細頁面上展示的數據來自多個微服務。以下是一些可能擁有特定商品頁面展示的數據的微服務:

  • 訂單服務 - 訂單歷史
  • 目錄(catalog)服務 - 基本的產品信息,如產品名稱、圖片和價格
  • 評價服務 - 客戶評價
  • 庫存服務 - 低庫存警告
  • 配送服務 - 配送選項、期限和費用,由配送方的 API 單獨提供
  • 推薦服務 - 推薦類目

圖 2-2、將移動客戶端的需求映射到相關的微服務

我們需要決定移動客戶端如何訪問這些服務。讓我們來看看有哪些方式。

2.2、客戶端與微服務直接通信

理論上,客戶端可以直接向每個微服務發送請求。每個微服務都有一個公開的端點:

https://serviceName.api.company.name

該 URL 將映射到用於跨可用實例分發請求的微服務負載均衡器,要檢索特定的產品頁面信息,移動客戶端將向上述的每個微服務發送請求。

不幸的是,這種方式存在著挑戰與限制。第一個問題是客戶端的需求與每個微服務暴露的細粒度的 API 不匹配。此示例中,客戶端需要進行七次單獨請求。如果在更加複雜的應用中,它可能需要做更多的工作。例如,Amazon 展示了在產品頁面渲染中如何牽涉到數百個微服務。雖然客戶端可以通過 LAN 發送許多請求,但在公共互聯網下效率低下,在移動網路必然是不切實際。

客戶端直接調用微服務的另一個問題是有些可能使用了不是 web 友好的協議。一個服務可能使用 Thrift 二進位 RPC,而另一個則可能使用 AMQP 消息協議。這兩個協議無論是對於瀏覽器還是防火牆都是不友好的,最好是在內部使用。應用程式應該在防火牆之外使用 HTTP 或者 WebSocket 之類的協議。

這種方法的另一個缺點是它難以重構微服務。隨著時間推移,我們可能會想改變系統劃分服務。例如,我們可能會合併兩個服務或者將服務拆分為兩個或者多個。然而,如果客戶端直接與服務進行通信,實施這類的重構將變得非常困難。

由於存在這些問題,很少有客戶端直接與微服務進行通信。

2.3、使用 API 網關

通常更好的方法是使用 API 網關。一個 API 網關是一個伺服器,是系統的單入口點。它類似於面向對象設計模式中的門面(Facade)模式。API 網關封裝了內部系統架構,並針對每個客戶端提供一個定製的 API。它還可用於認證、監控、負載均衡、緩存和靜態響應處理。

圖 2-3 展示了 API 通常如何整合架構

使用 API 網關的微服務

API 網關負責請求路由、組合和協議轉換。所有的客戶端請求首先通過 API 網關,之後請求被路由到適當的服務。API 網關通常會通過調用多個微服務和聚合結果來處理一個請求。它可以在 Web 協議(如 HTTP 和 WebSocket)和用於內部的非 Web 友好協議之間進行轉換。

API 還可以為每個客戶端提供一個定製的 API。它通常會為移動客戶端暴露一個粗粒度的 API。例如,考慮一下產品詳細信息場景。API 網關可以提供一個端點 /productdetails?productid=xxx,如圖 2-3 所示,一個使用了 API 網關的微服務。允許移動客戶端通過一個單獨的請求來檢索所有產品詳細信息。API 網關通過調用各種服務(產品信息、推薦、評價等)並組合結果。

API 網關的一個很好的案例是 Netflix API 網關。Netflix 流媒體服務可用於數百種不同類型的設備,包括電視機、機頂盒、智能手機、游戲機和平板電腦等。起初,Netflix 嘗試為他們的流媒體服務提供一個通用的 API。但是,他們發現由於設備種類繁多,並且他們各自有著不同需求,所以並不是能很好地運作。如今,他們使用了 API 網關,通過運行特定設備適配代碼來為每個設備提供一個定製 API。

2.4、API 網關的優點和缺點

正如您所料,使用 API 網關同樣存在好處與壞處。使用 API 網關的主要好處是它封裝了應用程式的內部結構。客戶端只需要與網關通信,而不必調用特定的服務。API 網關為每種類型的客戶端提供了特定的 API,減少了客戶端與應用程式之間的往返次數。它還簡化了客戶端代碼。

API 網關也存在一些缺點,它是另一個高度可用的組件,需要開發、部署和管理。還有另一個風險是 API 網關可能會成為開發瓶頸。開發人員必須更新 API 網關以暴露每個微服務的端點。

重要的是更新 API 網關的過程應儘可能地輕一些。否則,開發人員將被迫排隊等待網關更新。儘管 API 網關存在這些缺點,但對於大多數的真實應用來說,使用 API 是合理的。

2.5、實施 API 網關

我們已經瞭解了使用 API 網關的動機與權衡。接下來讓我們看看您需要考慮的各種設計問題。

2.5.1、性能與可擴展性

只有少數公司能達到 Netflix 的運營規模,每天需要處理數十億的請求。然而,對於大多數應用來說,API 網關的性能和可擴展性是相當重要的。因此,在一個支持非同步、非阻塞 I/O 平臺上構建 API 網關是有必要的。可以使用不同的技術來實現一個可擴展的 API 網關。在 JVM 上,您可以使用基於 NIO 的框架,如Netty、Vertx、Spring Reactor 或者 JBoss Undertow。一個流行的非 JVM 選擇是使用 Node.js,它是一個建立在 Chrome 的 JavaScript 引擎的平臺。另一個選擇是使用 NGINX Plus。

NGINX Plus 提供了一個成熟、可擴展和高性能的 Web 伺服器和反向代理,它易於部署、配置和編程。NGINX Plus 可以管理身份驗證、訪問控制、負載均衡請求、緩存響應,並且提供了應用程式健康檢查和監控功能。

2.5.2、使用響應式編程模型

API 網關通過簡單地把他們(請求)路由到適當的後端服務來處理一些請求。它通過調用多個後端服務並聚合結果來處理其他請求。對於某些請求,如產品詳細信息請求,對後端服務請求而言是彼此獨立的。為了縮短響應時間到最小,API 網關應該併發執行獨立請求。

然而,有時候,請求是相互依賴的。首先,API 網關可能需要在將請求路由到後端服務之前,通過調用驗證服務來驗證請求。同樣,為了從客戶的願望清單中獲取關於產品的信息,API 網關首先必須檢索包含該信息的客戶資料,然後檢索每個產品的信息。API 組合的另一個有趣的案例是 Netflix 視頻網格

使用傳統的非同步回調方式來編寫 API 組合代碼會很快使你陷入回調地獄。代碼將會變得雜亂,難以理解,並且容易出錯。一個更好的方式是使用響應式方法以聲明式編寫 API 網關代碼。響應式抽象的例子包括 Scala 的 Future、Java 8 中的 CompletableFuture 和 JavaScript 中的 Promise。還有 Reactive Extensions(也稱為 Rx 或 ReactiveX),最初由 Microsoft 為 .NET 平臺開發。Netflix 為 JVM 創建了 RxJava,專門應用於其 API 網關。還有用於 JavaScript 的 RxJS,它可以在瀏覽器和 Node.js 中運行。使用響應式方式可讓您能夠編寫出簡單而高效的 API 網關代碼。

2.5.3、服務調用

一個基於微服務的應用程式是一個分散式系統,必須使用一個進程間(inter-process)通信機制。有兩種進程間通信方案。一是使用基於消息的非同步機制。某些實現採用了消息代理,如 JMS 和 AMQP。其他採用無代理的方式直接與服務通信,如 Zeromq。

另一種類型的進程間通信採用了同步機制,如 HTTP 和 Thrift。系統通常會同時使用非同步和同步方式。甚至可以為每種方式應用多個實現。因此,API 網關需要支持各種通信機制。

2.5.4、服務發現

API 網關需要知道與其通信的每個微服務的位置(IP 地址和埠)。傳統應用程式中,您可以將這些位置硬編碼,但在現代基於雲的微服務應用程式中,找到所需的位置不是一個簡單的問題。

基礎設施服務(比如消息代理)通常都有一個可以通過系統環境變數來指定的靜態位置。但是,要確定應用程式服務的位置並不是那麼容易。

應用服務可以動態分配位置。此外,由於自動擴展與升級,一個服務的整組實例可以動態變更。因此,API 網關與系統中的任何其他服務客戶端一樣,需要使用系統的服務發現機制:服務端發現客戶端發現。 第4章中更詳細地描述了服務發現。現在需要註意的是,如果系統使用客戶端發現,API 網關必須能夠查詢服務註冊表,該註冊表是所有微服務實例及其位置的資料庫。

2.5.5、處理部分故障

實施 API 網關時必須解決的另一個問題是部分故障問題。當一個服務調用另一個響應緩慢或者不可用的服務時,所有分散式系統都會出現此問題。API 網關不應該無限期地等待下游服務。但是,如何處理故障問題取決於特定的方案和哪些服務發生故障。例如,如果推薦服務在獲取產品詳細信息時沒有響應,API 網關應將其餘的產品詳細信息返回給客戶端,因為它們對用戶仍然有用。建議可以是空的,也可以用其他代替,例如硬編碼的十強名單。然而,如果產品信息服務沒有響應,那麼 API 網關應該向客戶端返回錯誤。

如果可以,API 網關還可以返回緩存數據。例如,由於產品價格變化不大,如果價格服務不可用,API 網關可以返回被緩存的價格數據。數據可以由 API 網關緩存或存儲在外部緩存中,如 Redis 或者 Memcached。API 網關通過返回預設數據或緩存數據,確保了系統發生故障時最小程度上影響到用戶體驗。

Netflix Hystrix 是用於編寫調用遠程服務代碼的一個非常有用的庫。Hystrix 可以使超出指定閾值的調用超時。它實現了斷路器模式,防止客戶端不必要地等待無響應的服務。如果服務的錯誤率超過指定閾值,Hystrix 將會跳閘,所有請求將在指定的時間內立即失敗。Hystrix 允許您在請求失敗時定義回退操作,例如從緩存讀取或返回預設值。如果您正在使用 JVM,那麼您一定要考慮使用 Hystrix。如果您是在非 JVM 環境中運行,則應使用同等作用的庫。

2.6、總結

對於大多數基於微服務的應用程式來說,實現一個 API 網關是很有意義的,API 網關充當著系統的單入口點,並且負責請求路由,組合和協議轉換。它為每個應用程式客戶端提供了一個自定義 API。API 網關還可以通過返回緩存或預設數據來掩蓋後端服務故障。在下一章中,我們將介紹服務間的通信。

微服務實戰:NGINX Plus 作為 API 網關

by Floyd Smith

本章討論了 API 網關如何作為系統的單入口點。它可以處理諸如負載均衡、緩存、監控和協議轉換等其他功能 —— 當 NGINX 充當一個反向代理伺服器時,可以作為系統的單入口點,並且支持所有提到的一個 API 網關具有的附加功能。因此使用 NGINX 作為 API 網關的主機可以很好地工作。

將 NGINX 作為 API 網關並不是本書最開始的想法。NGINX Plus 是用於管理和保護基於 HTTP 的 API 流量的領先平臺。您可以實現自己的 API 網關或使用現有的 API 管理平臺,其中許多使用了 NGINX。

使用 NGINX Plus 作為 API 網關的理由包括:

  • 訪問管理 - 上至典型的 Web 應用級別,下至每個個體微服務級別,您都可以使用各種訪問控制列表(ACL)方法,並且可以輕鬆實現 SSL/TLS。
  • 可管理性與彈性 - 您可以使用 NGINX 的動態重新配置 API、Lua 模塊、Perl 來更新基於 NGINX Plus 的 API 伺服器,也可以通過 Chef、Puppet、ZooKeeper 或 DNS 來改變。
  • 與第三方工具集成 - NGINX Plus 已經可以與某些先進的工具集成在一起,如 3scaleKongMuleSoft 集成平臺(僅列舉在 NGINX 網站上提及的工具)。

NGINX Plus 被廣泛用作 NGINX 微服務參考架構中的 API 網關。利用在這裡收集的文章以及 MRA (微服務參考架構)來瞭解如何在您自己的應用程式中實現這一點。


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

-Advertisement-
Play Games
更多相關文章
  • re模塊包含對 正則表達式。本章會對re模塊主要特征和正則表達式進行介紹。 什麼是正則表達式 正則表達式是可以匹配文本片段的模式。最簡單的正則表達式就是普通字元串,可以匹配其自身。換包話說,正則表達式’python’ 可以匹配字元串’python’ 。你可以用這種匹配行為搜索文本中的模式,並且用計算 ...
  • 註:本文轉載自趙學智@行勝於言《什麼是對象,為什麼要面向對象,怎麼才能面向對象?》 地址:http://www.cnblogs.com/seesea125/archive/2012/04/03/2431176.html 一、 面向對象,這個對象到底是什麼? 這個對象不是C#中的實例,C#中我們把一個 ...
  • 1.抽象的產品類 2.抽象的工廠類 3.客戶端的程式 至此,以上都是應用抽象工廠基本不變的代碼。接下來就是具體的實現類,也就是根據變化的需求給出變化的代碼 4.具體產品類 5.具體工廠類 6.應用 ...
  • 伺服器設置 1. 安裝64位JDK; 2. 設置Linux文件系統為Ext4 3.開啟2181,7771,7772防火牆埠 源碼編碼 1. 安裝Maven 2. 安裝OpenSesame 下載地址:https://github.com/alibaba/opensesame.git,將openses ...
  • 使用裝飾者模式,可以動態的給一個對象添加一些額外的職責。這適用於,我們只希望給某個對象而不是整個類添加一些功能的場景。通過使用含有某個特定功能的類來“包裹”原始的類,提供給原始的類某些它本身不具備的特性。比如,我們有一杯“茉莉茶”,現在加上一顆“檸檬”,那我們就有了一杯“檸檬茉莉花茶”。“檸檬”作為... ...
  • 驗幻空越重,命循頻異長。依輪線日簡,接偶正分壯。言歡空月蟲,明勛品宜昌。依倫先日賤,潔偶正粉妝。 ...
  • 線程池中緩存線程的集合就是個單例 ...
  • 之前一直聽一些大牛談論什麼架構、框架,給我的直觀感覺就是一樣的,但是看瞭如下博文,我恍然大悟,原來是兩碼事。 人們對軟體架構存在非常多的誤解,其中一個最為普遍的誤解就是:將架構(Architecture)和框架(Framework)混為一談。其實很簡單,一句話:框架是軟體,架構不是軟體。框架落腳在“ ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...