1. 程式人生 > >談談 API 閘道器

談談 API 閘道器

 

背景

理論上,客戶端可以直接向微服務傳送請求,每個微服務都有一個公開的URL,該URL將對映到微服務的負載均衡器,由它負責在可用例項之間分發請求。但這種方式存在如下缺陷:

 

1. 客戶端需求和微服務暴露的細粒度 API 不匹配

經常有一個業務呼叫很多個服務,假如客戶端傳送許多請求,這在公網上可能會很低效,而且會使客戶端程式碼變得更復雜。

 

2. 服務使用的協議不是 Web 友好的

有的服務可能使用二進位制 RPC(比如 thrift),有的服務可能使用 AMQP 訊息傳遞協議。不管哪種協議都不是瀏覽器友好或防火牆友好的,最好是內部使用。在防火牆之外,應用程式應該使用諸如 HTTP 和 WebSocket 之類的協議。

 

3. 難重構

隨著時間推移可能想要更改系統劃分成服務的方式。例如,合併兩個服務或者將一個服務拆分成兩個或更多服務。如果客戶端與微服務直接通訊,那麼執行這類重構就很困難。

由於以上問題,客戶端與微服務直接通訊很少是合理的,更好的方法是使用 API 閘道器,由 API 閘道器作為後端服務系統的唯一入口。它封裝了系統內部架構,為每個客戶端提供一個定製的 API 。由它負責服務請求路由、組合及協議轉換。有的 API 閘道器還有其它職責,如身份驗證、監控、負載均衡、快取。

 

整體架構

完備的服務閘道器應該包括三大部分:API 閘道器、閘道器控制檯、度量資料採集分析。實際形態各異,可以按需搭建,但肯定少不了 API 閘道器,閘道器控制檯的功能職責可能會放到服務註冊等地方而沒有單獨抽取出來,至於度量資料採集可能會在整個微服務架構中存一個通用的度量資料採集應用以監控所有型別應用。

API服務閘道器整體架構

 

API 閘道器的優缺點

 

1. 優點

封裝了應用程式的內部結構。客戶端只需要同閘道器互動,而不必呼叫特定的服務。API 閘道器為每一類客戶端提供了特定的 API ,從而減少客戶端與應用程式間的互動次數,簡化客戶端程式碼的處理。

 

2. 缺點

增加了一個必須開發、部署和維護的高可用元件。還有一個風險是 API 閘道器變成了開發瓶頸。為了暴露每個微服務,開發人員必須更新 API 閘道器。API 閘道器的更新過程要儘可能地簡單,否則為了更新閘道器,開發人員將不得不排隊等待。不過,雖然有這些不足,但對於大多數現實世界的應用程式而言使用 API 閘道器是合理的。

 

實現的技術

 

1. 開發語言

對於大多數應用程式而言,API 閘道器的效能和可擴充套件性通常都非常重要。因此,API 閘道器將構建在一個支援非同步、I/O 非阻塞的平臺上。Java系可以使用一種基於 NIO 的框架,比如Netty、Vertx、Spring Reactor ,還可以使用 Node.js、NGINX Plus。

 

2. 響應式程式設計

API 閘道器通過簡單地將請求路由給合適的後端服務來處理部分請求,而通過呼叫多個後端服務併合並結果來處理其它請求。對於沒有依賴關係的請求,API 閘道器應該併發執行以最小化響應時間。使用傳統的非同步回撥方法編寫 API 組合程式碼會陷入回撥地獄。程式碼會變得混亂、難以理解、容易出錯。可以使用響應式程式設計以一種宣告式樣式編寫程式碼。比如 Scala 中的Future 、Java 8 中的 CompletableFuture 和 JavaScript 中的 Promise ,還有最初是微軟為 .NET 平臺開發的 Reactive Extensions(RX)。Netflix 建立了 RxJava for JVM ,專門用於他們的 API 閘道器。

 

3. 程序通訊模型

微服務的應用程式必定是一個分散式系統,所以必須使用程序間的通訊機制。有兩種型別的程序間通訊機制可供選擇。一種是使用非同步的、基於訊息傳遞的機制。有些實現使用諸如JMS 或 AMQP 那樣的訊息代理,而其它的實現(如 Zeromq )則沒有代理,服務間直接通訊。另一種是諸如 HTTP 或 Thrift 那樣的同步機制。通常,一個系統會同時使用非同步和同步兩種型別。它甚至還可能使用同一型別的多種實現。總之,API 閘道器需要支援多種通訊機制。

 

4. 服務發現

API 閘道器需要知道它與之通訊的每個微服務的位置(IP 地址和埠)。應用程式服務的位置是動態分配的。而且,單個服務的一組例項也會隨著自動擴充套件或升級而動態變化。API 閘道器需要使用系統的服務發現機制,可以是伺服器端發現,也可以是客戶端發現。如果系統使用客戶端發現,那麼 API 閘道器必須能夠查詢服務註冊中心,這是一個包含所有微服務例項及其位置的資料庫。

Spring cloud 提供了服務註冊和發現功能,如果需要自己實現,可以考慮用 Zookeeper 作為登錄檔,客戶端用 Curator 。

 

5. 區域性失敗

在實現 API 閘道器時,還有一個問題需要處理,就是區域性失敗的問題。該問題在所有的分散式系統中都會出現,無論什麼時候,當一個服務呼叫另一個響應慢或不可用的服務,就會出現這個問題。API 閘道器永遠不能因為無限期地等待下游服務而阻塞。不過,如何處理失敗取決於特定的場景以及哪個服務失敗。如果快取資料可用,那麼 API 閘道器還可以返回快取資料。資料可以由API閘道器自己快取,也可以儲存在像 Redis 或 Memcached 那樣的外部快取中。通過返回預設資料或者快取資料,API 閘道器可以確保系統故障不影響使用者的體驗。

在編寫程式碼呼叫遠端服務方面,Netflix Hystrix 是一個異常有用的庫。Hystrix 會將超出設定閥值的呼叫超時。它實現了一個“斷路器(circuit breaker)”模式,可以防止客戶端對無響應的服務進行不必要的等待。如果服務的錯誤率超出了設定的閥值,那麼 Hystrix 會切斷斷路器,在一個指定的時間範圍內,所有請求都會立即失敗。Hystrix 允許使用者定義一個請求失敗後的後援操作,比如從快取讀取資料,或者返回一個預設值。如果你正在使用 JVM,那麼你絕對應該考慮使用 Hystrix 。而如果你正在使用一個非 JVM 環境,那麼你應該使用一個等效的庫。

 

6.參考實現方案

以上列出在 DIY 這個 API 閘道器時需要考慮的點,以及參考的技術實現。下面是幾種目前比較流行的 API 閘道器搭建的技術方案供參考,後續文章將給出這些方案搭建的例子

1)Nginx + Lua實現負載均衡、限流、服務發現等功能

2)使用 spring cloud 技術棧,其中 zuul 就是用作 API 閘道器的

3)Mashape 的開源 API 閘道器 Kong

 

7.閘道器控制檯

提供 domain 管理、應用管理、服務授權、服務監控、統計和度量資料展示、檢視服務全域性檢視等功能。服務消費者和服務提供者都要在閘道器控制檯進行應用註冊,控制檯為每個應用分配應用id(appId唯一)和應用金鑰(appSecret)。註冊時需要提供的資訊:應用名稱、應用描述、應用負責人相關資訊。

 

                                                           
                                                                    掃一掃,支援下作者吧

                                             (轉載本站文章請註明作者和出處 方誌朋的部落格