推薦閱讀:
背景
我們都知道,在微服務架構風格里,一個應用會被拆分成多個小的服務系統,並且這些小系統都可以自成體系,可以擁有自己的數據庫、框架語言等。它們通常都可以提供接口來被各種應用程序調用。
但是在UI上進行展示的時候,我們通常需要在一個界面上展示很多數據,這些數據可能來自於不同的微服務中。
打個比方:要查看一個電商平臺的商品詳情頁,這個商品詳情頁包括標題、價格、庫存、評價等等,這些數據可能在不同的微服務系統之中,如下所示:
- 產品 - 負責提供商品的標題,描述,規格等。
- 價格 - 負責對產品進行定價,價格策略計算,促銷價等。
- 庫存 - 負責產品庫存。
- 評價 - 負責用戶對商品的評論,回覆等。
現在,商品詳情頁需要從這些微服務中拉取相應的信息,問題來了?
由於用的是多個服務系統的架構,所以依靠單個數據庫的 join 查詢結果不可行,那麼該怎麼訪問各個服務呢?
按照微服務設計的指導原則,我們的微服務可能存在下面的問題:
- 服務使用了多種協議,因爲不同的協議有不同的應場景用,比如可能同時使用 HTTP, AMQP, gRPC 等。
- 服務的劃分可能隨着時間而變化。
- 服務的實例或者Host+端口可能會動態的變化。
那麼,對於前端的UI需求也可能會有以下幾種:
- 粗粒度的API,而微服務通常提供的細粒度的API,對於UI來說如果要調用細粒度的api可能需要調用很多次,這是個不小的問題。
- 不同的客戶端設備可能需要不同的數據。Web,H5,APP
- 不同設備的網絡性能,對於多個api來說,這個訪問需要轉移的服務端會快得多
那麼如何解決呢?
這種情況下,我們就需要一個今天要講的這個東西, API 網關(API Gataway)。
API 網關
下面是百度上針對於 API 網關的介紹:
API網關是一個服務器,是系統的唯一入口。從面向對象設計的角度看,它與外觀模式類似。API網關封裝了系統內部架構,爲每個客戶端提供一個定製的API。它可能還具有其它職責,如身份驗證、監控、負載均衡、緩存、請求分片與管理、靜態響應處理。
API網關方式的核心要點是,所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能。通常,網關也是提供REST/HTTP的訪問API。服務端通過API-GW註冊和管理服務。
Chris Richardson 在他的博客中把 API 網關劃分爲以下兩種:
- 單節點 API 網關
- Backends for frontends 網關
單節點網關
單節點的 API網關爲每個客戶端提供不同的API,而不是提供一種萬能風格的API。
這個網關和微軟在 eShop 項目中推薦的網關是一致的。
Backends for frontends 網關
這種模式是針對不同的客戶端來實現一個不同的API網關。
落地方案
以上兩種 API 網關有什麼問題呢?
通常情況下, API 網關要做很多工作,它作爲一個系統的後端總入口,承載着所有服務的組合路由轉換等工作,除此之外,我們一般也會把安全,限流,緩存,日誌,監控,重試,熔斷等放到 API 網關來做,那麼可以試想在高併發的情況下,這裏可能會出現一個性能瓶頸。
另外,如果沒有開源項目的支撐前提下,自己來做這樣一套東西,是非常大的一個工作量,而且還要做 API 網關本身的高可用等,如果一旦做不好,有可能最先掛掉的不是你的其他服務,而就是這個API網關。
這個時候,通常我們會去找一些開源的 API 網關項目,博主已經給你找好了,目前社區的關於 API Gataway 的項目有以下這些:
Goku:Goku是一個可擴展的開放源碼API Layer(也稱爲API網關或API中間件)。開箱即用,全界面配置,操作簡單,通過插件擴展,它提供了超越核心平臺的額外功能和服務。
Orange:基於OpenResty的一個API網關程序,同樣是由國人開發的。
Netflix zuul:Zuul是一種提供動態路由、監視、彈性、安全性等功能的邊緣服務。Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器。
apiaxle: Nodejs 實現的一個 API 網關。
api-umbrella: Ruby 實現的一個 API 網關。
總結
通過本文我們瞭解到了什麼是 API 網關以及API網關的作用和其在微服務架構中所處的地位。然後我們瞭解到了 API 網關的一些開源項目以及博主介紹的落地方案,在實際的實踐中還是多希望大家能夠多多思考總結,這樣我們才能夠變得更加強大。