API閘道器(API Gateway)
模式:API閘道器
背景
我們假設你使用微服務模式建立一個線上商店,並正在實現商品詳情頁面。你需要開發多個版本的商品詳情使用者介面:
-
用於桌面和手機瀏覽器的基於HTML5/JavaScript的UI - HTML通過服務端web應用生成
-
本地Android和iPhone客戶端 - 這些客戶端通過REST API與伺服器互動
另外,線上商店應該通過REST API為第三方公開商品詳情。
商品詳情可以展示商品的許多資訊。比如,Amazon.com上POJOs in Action詳情頁顯示:
-
圖書的基本資訊,如標題,作者,價格等
-
圖書的購買歷史
-
是否有貨
-
購買引數
-
與這本書同時被購買的商品
-
購買了這本書的使用者還買了什麼
-
使用者評論
-
銷售者的評分
-
...
既然線上商店使用了微服務模式,商品詳情資料通過服務來展開。如:
-
商品資訊服務(Product Info Service) - 商品基本資訊如標題,作者
-
價格服務(Pricing Service) - 商品價格
-
訂單服務(Order service) - 商品購買歷史
-
庫存服務(Inventory service) - 商品是否有貨
-
評論服務(Review service) - 使用者評論 ...
因此,顯示商品詳情的程式碼需要從所有這些服務獲取資訊。
問題
基於微服務應用的客戶端如何訪問這些獨立服務?
推動力
-
微服務提供的API粒度通常與客戶端的需求不同。微服務一般提供細粒度的API,這意味著客戶端需要與多個服務進行互動。比如上面提到的,需要商品詳情的客戶端要從大量服務拉取資料。
-
不同的客戶端需要不同的資料。比如,商品詳情頁面的桌面版通常比手機版更詳細。
-
不同型別客戶端的網路效能不同。如,行動網路一般比非行動網路更慢,延遲更高。當然,廣域網(WAN)比區域網(LAN)要慢得多。這意味著手機本地客戶端使用的網路與服務端web應用的LAN的效能特點區別很大。服務端web應用可以在不影響使用者體驗的情況下,向後端服務傳送大量請求,但手機客戶端只能傳送少量的請求。
-
服務的劃分可能會隨時間而變化,因此需要對客戶端隱藏。
解決方案
實現一個API閘道器作為所有客戶端的唯一入口。API閘道器有兩種方式來處理請求。有些請求被簡單地代理/路由到合適的服務上,其他的請求被轉給到一組服務。
相比於提供普適的API,API閘道器根據不同的客戶端開放不同的API。比如,Netflix API閘道器執行著客戶端特定的介面卡程式碼,會向客戶端提供最適合其需求的API。
API閘道器也可以實現安全性,比如驗證客戶端是否被授權進行某請求。
舉例
結果
使用API閘道器有如下好處:
-
向客戶端隱藏了應用如何被劃分到微服務的
-
向每個客戶端提供最優API
-
將呼叫大量服務的邏輯轉到API閘道器,因而簡化了客戶端
-
減少了請求/往返數量。比如,API使客戶端可以在一趟請求中向多個服務拉取資料。請求少了,開銷就少了,因此提升了使用者體驗。API閘道器對手機應用來說是非常必要的。
API閘道器模式也有一些缺點:
-
增加了複雜度 - API閘道器自身也是一個需要被開發、部署和管理的部分。
-
增加了響應時間,因為多了API閘道器這個網路躍點 - 但是,對絕大部分應用,多一次往返的開銷是不明顯的。
問題:
-
如何實現API閘道器?如果為了伸縮以處理高負載,事件驅動/反應式(reactive)方法是最好的。在JVM上,基於NIO的庫,如Netty, Spring Reactor也可以。NodeJS是另一選擇。
相關模式
微服務模式提供了對該模式的需求。