API 網關(API Gateway)提供高性能、高可用的 API 託管服務,幫助用戶對外開放其部署在 ECS、容器服務等雲產品上的應用,提供完整的 API 發佈、管理、維護生命週期管理。用戶只需進行簡單的操做,便可快速、低成本、低風險地開放數據或服務。前端
背景git
咱們知道在微服務架構風格中,一個大應用被拆分紅爲了多個小的服務系統提供出來,這些小的系統他們能夠自成體系,也就是說這些小系統能夠擁有本身的數據庫,框架甚至語言等,這些小系統一般以提供 Rest Api 風格的接口來被 H5, Android, IOS 以及第三方應用程序調用。github
可是在UI上進行展現的時候,咱們一般須要在一個界面上展現不少數據,這些數據可能來自於不一樣的微服務中,舉個例子。數據庫
在一個電商系統中,查看一個商品詳情頁,這個商品詳情頁包含商品的標題,價格,庫存,評論等,這些數據對於後端來講多是位於不一樣的微服務系統之中,可能我後臺的系統是這樣來拆分個人服務的:後端
如今,商品詳情頁須要從這些微服務中拉取相應的信息,問題來了?api
因爲咱們使用的服務系統架構,因此沒辦法像傳統單體應用同樣依靠數據庫的 join 查詢來獲得最終結果,那麼如何才能訪問各個服務呢?緩存
按照微服務設計的指導原則,咱們的微服務可能存在下面的問題:安全
那麼,對於前端的UI需求也可能會有如下幾種:服務器
以上,就是咱們構建微服務的過程當中可能會遇到的問題。那麼如何解決呢?網絡
這種狀況下,咱們就須要一個今天要講的這個東西, API 網關(API Gataway)。
下面是百度上針對於 API 網關的介紹:
API網關是一個服務器,是系統的惟一入口。從面向對象設計的角度看,它與外觀模式相似。API網關封裝了系統內部架構,爲每一個客戶端提供一個定製的API。它可能還具備其它職責,如身份驗證、監控、負載均衡、緩存、請求分片與管理、靜態響應處理。
API網關方式的核心要點是,全部的客戶端和消費端都經過統一的網關接入微服務,在網關層處理全部的非業務功能。一般,網關也是提供REST/HTTP的訪問API。服務端經過API-GW註冊和管理服務。
Chris Richardson 在他的博客中把 API 網關劃分爲如下兩種:
單節點網關
單節點的 API網關爲每一個客戶端提供不一樣的API,而不是提供一種萬能風格的API。
這個網關和微軟在 eShop 項目中推薦的網關是一致的。
更多詳細信息我會在下文進行說明。
Backends for frontends 網關
這種模式是針對不一樣的客戶端來實現一個不一樣的API網關。
我一直在尋思一種最佳的 API 網關的落地方案,以上兩種 API 網關有什麼問題呢?
一般狀況下, API 網關要作不少工做,它做爲一個系統的後端總入口,承載着全部服務的組合路由轉換等工做,除此以外,咱們通常也會把安全,限流,緩存,日誌,監控,重試,熔斷等放到 API 網關來作,那麼能夠試想在高併發的狀況下,這裏可能會出現一個性能瓶頸。
另外,若是沒有開源項目的支撐前提下,本身來作這樣一套東西,是很是大的一個工做量,並且還要作 API 網關自己的高可用等,若是一旦作很差,有可能最早掛掉的不是你的其餘服務,而就是這個API網關。
這個時候,一般咱們會去找一些開源的 API 網關項目,博主已經給你找好了,目前社區的關於 API Gataway 的項目有如下這些:
Tyk:Tyk是一個開放源碼的API網關,它是快速、可擴展和現代的。Tyk提供了一個API管理平臺,其中包括API網關、API分析、開發人員門戶和API管理面板。Try 是一個基於Go實現的網關服務。
Kong:Kong是一個可擴展的開放源碼API Layer(也稱爲API網關或API中間件)。Kong 在任何RESTful API的前面運行,經過插件擴展,它提供了超越核心平臺的額外功能和服務。
Orange:和Kong相似也是基於OpenResty的一個API網關程序,是由國人開發的,學姐也是貢獻者之一。
Netflix zuul:Zuul是一種提供動態路由、監視、彈性、安全性等功能的邊緣服務。Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器。
apiaxle: Nodejs 實現的一個 API 網關。
api-umbrella: Ruby 實現的一個 API 網關。
咱們來講說上面的這些開源項目適不適合做爲 API 網關來供咱們使用。
拿單節點網關來講,這種網關至關因而處於 Web 層和 Service 之間,用來聚合服務的?注意,咱們須要的是聚合服務,而以上這些開源項目都不具有這個功能,我說的聚合具體指的是開箱即用。咱們要想使用這些服務須要來本身對API網關過一些擴展或者是開發一些插件,這個時候問題就來了。擴展Tyk我須要會Go語言,擴展Kong我須要會寫lua腳本,使用 zuul 還得會Java,這對於開發人員來講是不太現實的,那麼這個時候怎麼辦?
有些同窗可能會說 ASP.NET Core 可使用 Ocelot,說得沒錯,咱們能夠經過引入Ocelot來處理API聚合服務這一塊的業務,可是,這中間有一個問題,就像我在上面說的同樣,這很容易形成性能問題,另一方面,Ocelot的功能相比上面的那些開源項目來講功能要弱不少,具體體如今哪些方面呢?
除了最重要的高性能的IO模型和集羣方案外, 好比會常用的 Dashboard 功能,這個對於運維來講是很是重要的,另外還有日誌,監控,安全,服務發現,版本控制等。
可是上面的這些 API 網關缺乏什麼功能呢? 好比超時,熔斷,重試,聚合查詢等。
注意:如下內容的這些想法全是我我的對於 API 網關的理解而誕生的,若有錯誤還請指正。
聰明的同窗可能想出來了,怎麼辦呢? 咱們能夠充分來結合二者的優點來在咱們的 ASP.NET Core 應用程序中實現一個「雙重網關」。
下面是我畫的一個 API 網關在微服務架構中的一個做用圖:
應該大部分同窗均可以看懂,我就簡單解釋一下。
從左至右 HTTP 請求先由DNS在拿到第一手流量後負載均衡到基於 OpenResty 的 API Gataway 網關集羣,在這個流程咱們可使用像 Kong,Orage,Tyk 這些開源的支持高併發高訪問量 API 網關程序在作第一層流量的防禦,在這一級咱們能夠作一些像身份認證,安全,監控,日誌,流控等策略。除了這些咱們還能夠作一些服務的發現和註冊(這個要看不一樣網關的支持程度),接口的版本控制,路由重寫等。
而後再由這些 API 網關把請求再負載到不一樣的 Aggr Api Gateway,在這裏咱們作聚合服務這個操做,具體體現也就是圖中的黃色區域是須要由各個語言的開發人員來須要寫代碼實現的。具體流程也就是咱們能夠引入像 Ocelot 這種和語言相關的 API 網關開源項目,而後經過 NuGet 包引入以後經過 Json配置+聚合代碼的方式來整合後端的各個微服務提供聚合查詢等操做。這期間對於有需求的接口,咱們能夠應用超時,緩存,熔斷,重試等策略。
從 Aggr Api Gateway 到後端微服務集羣這中間就屬於內部的通信了,咱們可使用對內部友好的通信協議好比 gRPC 或者 AMQP 等,而後進行 RPC調用提升通信性能。
注意:Aggr Api Gateway 這個網關對於一些接口來講的話並非必須的,也能夠由後端微服務直接提供REST API給第一層網關使用。
以上,就是我理解的 API 網關在整個微服務架構中的一個地位,承上啓下,仍是很是的重要。
咱們知道,在 API 網關的後端是微服務的集羣,那麼除了聚合查詢以外有時候咱們有時候須要作一些跨不一樣服務的操做,好比一次電商系統的下單操做,能夠會設計到產品、價格、庫存等一系列跨微服務操做,在中間咱們通常會採用集成事件(EventBus)來進行通信這種解決方案,在這個過程當中咱們不只僅的是須要通信,那麼這些操做還須要保證事務一致性,而通常分佈式系統中的事務咱們追求的是最終一致性。
若是是在 .NET Core 中,咱們可使用博主開源的 EventBus + 分佈式事務 解決方案 CAP。
GitHub:https://github.com/dotnetcore/CAP
有關分佈式事務能夠查看個人這篇文章。
感興趣的同窗能夠給CAP一個 Star 以表支持,偷偷告訴你 Ocelot的做者也Star了哦。 :)
經過本文咱們瞭解到了什麼是 API 網關以及API網關的做用和其在微服務架構中所處的地位。而後咱們瞭解到了 API 網關的一些開源項目以及博主介紹的落地方案,在實際的實踐中仍是多但願你們可以多多思考總結,這樣咱們纔可以變得更增強大。
若是你對 .NET Core 有興趣的話能夠關注我,我會按期的在博客分享個人學習心得。