万字讲解API网关的来龙去脉
點擊上方?好好學java?,選擇?星標?公眾號
重磅資訊、干貨,第一時間送達今日推薦:2020年7月程序員工資統計,平均14357元,又跌了,扎心個人原創100W+訪問量博客:點擊前往,查看更多本文作者:人月神話? ?
出處:blog.sina.com.cn/
s/blog_493a84550102z8x4.html
序
今天準備再詳細講解下 API 網關的基礎概念,使用場景和核心功能,以及基于 API 網關核心引擎做的 API 全生命周期管理功能擴展等,最好再介紹下當前主流的開源 API 網關引擎。
API 網關概述
在微服務架構體系里面,我們一般會使用到微服務網關或叫 API 網關。
大家都比較清楚,在微服務架構體系下本身是去中心化的架構,通過服務注冊中心來實現服務注冊發現和消費調用,那么為何又需要使用 API 網關?
在傳統的 ESB 總線進行服務集成的時候我們就經常談到一個概念就是位置透明,即需要屏蔽底層業務模塊提供 API 接口服務地址信息,并實現多個微服務 API 接口的統一出口。即類似設計模式里面經常談到的門面模式。
如何給 API 網關一個定義?
簡單來說 API 網關就是將所有的微服務提供的 API 接口服務能力全部匯聚進來,統一接入進行管理,也正是通過統一攔截,就可以通過網關實現對 API 接口的安全,日志,限流熔斷等共性需求。如果再簡單說下,通過網關實現了幾個關鍵能力。
內部的微服務對外部訪問來說位置透明,外部應用只需和網關交互 統一攔截接口服務,實現安全,日志,限流熔斷等需求
從這里,我們就可以看到 API 網關和傳統架構里面的 ESB 總線是類似的,這些關鍵能力本身也是 ESB 服務總線的能力,但是 ESB 服務總線由于要考慮遺留系統的接入,因此增加了:
大量適配器實現對遺留系統的遺留接口適配,多協議轉換能力 進行數據的復制映射,路由等能力
對于兩者,我原來做過一個簡單的對比,大家可以參考。
這個概念理解后,我們再回到微服務架構里面。
對于微服務架構大家經常說的最多的就是去中心化的架構,認為 ESB 中心化架構模式已經過時。而實際上經過上面分析你可以看到。在微服務架構里面的 API 網關仍然是中心化的架構模式,所有的 API 接口都要經過網關這個點。
非中心化架構-》走微服務里面的服務注冊中心進行接口交互
中心化架構-》走網關進行接口服務暴露和共享交互
對于微服務架構里面有無去中心化的架構?當然是有的,即我們常說的微服務模塊之間可以通過服務注冊中心來實現服務發現查找,服務間的點對點調用即使去中心化的。
如果一個單體拆分為微服務后,完全不需要和外部應用打交道,也不需要共享自己的接口能力,那么這個微服務體系里面就不需要用 API 網關,僅僅使用服務注冊中心即可。通過服務注冊中心實現完全的去中心化和接口調用更高的性能。
什么時候需要使用 API 網關?
如果一個微服務架構下,雖然不會外部的其它應用進行交互和集成,但是整個應用本身存在 APP 應用端,而 APP 應用端通過前后端分析開發,同時需要通過互聯網訪問。本身存在需要一個統一訪問 API 訪問入口,同時也需要考慮和內部微服務模塊進一步進行安全隔離。
當我們談到這里的時候,你會發現我們常說的 API 網關的服務代理或透傳能力,實際和我們常說的 Ngnix 反向代理或路由是一個意思。
如果你僅僅是為了統一 API 接口的訪問出口,并考慮類似 DMZ 區的安全隔離,那么在你架構前期完全不需要馬上實施 API 網關,直接采用 Ngnix 進行服務路由代理即可。因為在這種架構下,API 接口消費端,提供端全部是一個開發團隊開發,各種問題分析排查都相當方便,類似 API 接口安全訪問等也可以通過 JWT,Auth2.0 等統一實現,而且這個過程也并不復雜。
能力開放或多應用外部集成對 API 管控治理需要
但是當我們面臨是和多個外部應用集成,或者說將自己的 API 接口服務能力開放給外部多個合作伙伴使用的時候,這個時候對于 API 接口的管控治理要求自然增加。
即在常規的服務代理路由基礎上,需要增加類似負載均衡,安全,日志,限流熔斷等各種能力,而且我們不希望這些能力在 API 接口開發的時候考慮,而是希望這些能力是在 API 接入到網關的時候統一靈活配置來實現管控。
那么這個時候使用 API 網關作用就體現出來。
API 網關核心功能說明
對于 API 網關實際上前面已經多次強調,可以看做是 ESB 總線的輕量化實現,不再需要復雜的協議轉換,適配和數據映射等能力,但是提升了流量控制和安全,實時監控等方面的能力。對于 API 網關引擎部分提供的核心功能,再簡單總結如下:
1.實現統一服務代理和服務統一出口
這點是網關和常規點對點服務注冊中心最大的一個區別點,就是位置透明,消費端只需要和網關打交道,具體網關如何和后臺的微服務模塊打交道,后臺微服務模塊的部署邏輯,模塊提供服務的 IP 地址等都不用關心。
由于實現了位置透明,帶來一點就是數據流必須通過網關,那么網關本身又成為了去中心的微服務架構中的中心化節點,那么就必須考慮網關節點的性能,可靠性和彈性擴展能力。
網關要實現位置透明,延伸出來對應的網關必須提供的能力就包括了
提供服務注冊和服務接入的能力
提供服務代理和服務路由能力,能夠將服務路由到具體的原始服務上
提供負載均衡能力(該點并不是必須具備)
在這里準備重點強調下負載均衡能力,實際上對于 API 網關往往并不是必須具備負載均衡能力。
其一是提供 API 接口服務的模塊本身進行了負載均衡,再提供地址
其二是類似容器化集成和部署,已經可以通過 Kubernetes 實現了負載均衡
我們可以看下對于注冊和接入到 API 網關服務的三種場景,只有場景一需要由 API 網關來提供負載均衡能力。
注意 API 網關是否需要具備負載均衡能力,是必須考慮的一個點,即如果底層微服務模塊提供的 API 接口服務本身能夠提供負載均衡后的地址,那么網關不需要進行負載均衡。如果底層模塊不具備這個能力,那么網關必須具備負載均衡能力。
微服務模塊本身可以基于容器化資源池提供的能力進行動態擴展,因此這個地方本身又有兩層負載均衡,一個是 kubernates 提供的集群能力,一個是多個 API 網關本身提供的集群能力。當然 API 網關本身也具備負載均衡功能,可以和 Kubernate 進行銜接。
2. 通過網關的攔截能力來實現所有共性能力抽取和實現
剛才已經談到啟用網關后就承載了數據流,因此可以通過對接口訪問輸入和輸出的攔截來實現所有共性可復用能力的抽取和實現。這些共性能力可以理解為網關實現的一個個攔截插件,本身可插拔,靈活可配置。
這些插件能力中最核心的就是安全,日志,流控。
其中安全可以實現訪問安全,傳輸安全,數據安全等,其中訪問安全本身又可以實現類似 Token,IP,用戶名密碼等多種安全控制策略。包括對 Auth2.0 等標準規范的支持等。
對于日志也是網關提供的一個關鍵能力,即可以實現對服務消費日志,詳細的輸入和輸出報文的查詢能力,這個在各開源網關往往并不具備這個能力,也無法面向業務系統人員去使用,因此這塊能力提升往往都需要在開源網關基礎上做大量擴展。
流控是我們談的另外一個關鍵能力,包括了服務限流和服務熔斷。對于服務限流主要是實現對服務消費前線程數控制,資源分配實現消費前等待。而對于服務熔斷,即直接對服務進行下線或禁用,以避免大并發服務消費調用對網關造成的影響或帶來的服務雪崩等。
一個網關來說,流控能力相對關鍵,因為網關是中心化節點,必須保證網關的高可靠運行。因此網關流控能力強弱直接影響到網關的高可靠性和性能,而判斷流控能力強弱的關鍵則在于靈活的流量控制策略配置,只有這樣才能夠做到既實現流控,又不影響到關鍵業務和接口服務的訪問。
3. 滿足前后端分離的需求
注意,如果一個企業開發的業務系統涉及到手機 APP 端,而手機 APP 端一定涉及到公網訪問,按業務系統內部部署安全策略也一定涉及到 DMZ 區的設置和硬件防火墻隔離。
而對于 API 網關本身恰好又是可以部署到 DMZ 區的一個內容,既實現了服務代理路由,又實現了安全隔離,如果存在這種場景,即使業務應用不和外部系統打交道,為了前后端的隔離和外部訪問,往往也需要 API 網關能力支撐。當然前期你也可以使用 Ngnix 來替代 API 網關實現統一代理。
4. 灰度發布或金絲雀發布
這個在我原來談網關的文章的時候很少談到這點,但是實際上在 DevOps 和微服務架構實施下,對于灰度發布能力往往也是必須的。比如我們對已有的一個接口服務做了修改,我們想先在某些業務系統試用,沒有問題再發布到所有的業務系統。這個時候就涉及到金絲雀發布的問題。當然你可以配置是按系統,按 IP,按用戶還是其他的發布策略。
這塊的能力不僅僅是 DevOps 的自動部署,同時也必須考慮網關層能夠基于動態發布的內容進行路由。確保服務調用消費的路由路徑是隔離開的。而對于金絲雀發布策略允許你直接只導入指定量的流量到新的版本,API 網關就可以幫你來做這件事情。你可以配置 10%的請求到新的版本,然后一旦你確保了新版本沒有 bug,你可以把流量切換到 100%。
5. 服務組合能力
實際上當我們談 API 網關的時候,一般不會談服務組合能力,因為一涉及到服務組合或編排,那么必然導入網關整體架構變重。從當前主流網關看,一般也不提供類似能力。
實際上服務組合編排難點在于,上個服務的輸出往往要成為下一個服務的輸入,同時服務輸入和輸出還存在大量的數據映射操作。我們回顧下類似智慧家庭里面的組合場景編排,實際上很簡單,比如我回到家后需要打開空調,關窗簾,打開熱水器,開燈的一系列動作,我只是需要簡單將這些動作編排在一起。
對應到 API 網關的服務組合,實際上我們也可以做輕量的服務組合,即去掉數據映射等復雜組合場景,只需要實現簡單的服務多次調用,服務返回數據的組合等即可。
對于具體的服務組合和編排,可以參考下面這篇文章:
從 ESB 服務組合編排到 NetflixConductor 微服務編排
API 全生命周期管理能力
可以看到,API 網關更多是一個底層引擎,而要實現完整的 API 管控,往往還需要配合 API 全生命周期管理能力。這個完全可以在底層 API 網關引擎基礎上進行擴展開發。
API 接口的定義
在定義 API 接口的時候首先要定義 API 分組,這個從京東,淘寶等 OpenAPI 能力開放平臺的 API 文檔都可以看到,首先要有 API 歸類分組,然后再定義詳細的 API。
比如京東開放平臺,有商品,店鋪,倉儲,支付等多個類目,然后各類目下有詳細的 API 的定義。
API 的定義包括兩個部分,一個是 API 基本信息定義,一個是詳細輸入輸出定義。
API 基本信息仍然是包括了 API 的編碼,API 名稱,API 的分組,API 的用途描述,API 的緩存,安全等基本控制信息的定義等。還有就是這個 API 接口的訪問路徑定義,API 接口是 Get 還是 Post 方法定義等。
API 詳細信息主要就是 API 的輸入和輸出信息定義。
API 的輸入參數注意實際有多種形式,一個就是在 API 訪問路徑上的路徑參數,還有一個就是在訪問路徑后?參數后面的查詢參數信息,還有就是一個完整的 Request Body 請求參數信息。
比如對于 Http Rest 查詢接口,這類 Get 方法接口,可以看到并沒有 Body 信息,更多的是通過路徑和查詢參數定義來完成查詢。而對于 Post 接口往往就涉及到具體的 Body 信息定義。
但是要注意,為了實現 Http Rest 接口和 SOAP WS 接口服務的互相轉換,對于 SOAP WS 查詢服務接口在自動轉換為 Http Rest 接口服務的時候實際上仍然為轉換為 Post 方法+Body 參數模式。
對于 API 接口定義,仍需要預留標準的系統級參數部分內容。這部分內容是 API 網關實現統一標準化管理的基礎,不能隨便修改和變動。比如京東 API 平臺預留的 API 名稱,方法,版本,Token,APP_Key,Date 等都是使用系統級別的參數定義,是每一個接口 API 暴露后都需要增加的參數頭信息。
API 快速開發的支持
在 API 接口服務定義完成后,一方面是可以通過類似 WADL 或 RAML 等標準的 Rest 接口定義規范文件,另外一個就是需要提供客戶端和服務端的開發框架代碼。
在這個基礎上,還可以提供完整的示例代碼下載,方便開發商或合作伙伴對 API 接口進行快速開發。開發完成的后端原始服務接口,在注冊接入前還可以提供接口服務的模型匹配自校驗功能,確認開發的服務完全遵循從上到下方式-》API 開發框架生成和 API 后端服務開發。
對于 API 接口管理,如果是標準的從頂朝下模式,即在定義了 API 接口后,實現生成類似 WADL 或 RAML 標準接口規范。后端服務基于我們標準的 API 接口契約進行開發,那么開發完成后就方便快速代理方式接入,在接入過程中就不再有參數映射和轉換的問題,否則我們的 API 接入過程會比較復雜。
API 接口服務的注冊和接入
API 接口定義過程和 API 接口的注冊接入最好分開。
在 API 接口定義完成后進行 API 接口服務的注冊,即選擇具體的后端服務,然后對服務進行接入。同時將后端服務對應到我們在前面定義的 API 接口代理服務上。注意在前面談到的 API 路徑定義,方法類型定義,實際上也可以在 API 接口服務注冊和接入的時候來完成。
API 接口服務的后續變更發布,還可以考慮和 DevOps 平臺配合并支持灰度發布功能。
反向的后端服務快速接入并發布為 API 接口服務,即直接對后端已有的 API 服務進行快速接入,將 API 后端服務發布為代理服務,在整個接入過程中需要定義 API 接口名稱,API 訪問路徑,API 方法類型等信息。在發布為 API 接口服務后,對于后端服務的 API 參數信息也需要進行快速導入,以方便在 API 接口查詢中看到詳細的接口內容定義。
在將后端業務服務發布為 API 接口服務的時候,發布的代理服務要自動增加系統級的輸入參數信息,這個輸入參數最好的方式是在訪問路徑中進行增加,以減少對已有的后端服務的影響。
API 接口在注冊和接入完成后,將自動進行服務部署和服務發布,即注冊接入完成后的服務可以通過發布的訪問路徑地址進行訪問。
服務接入適配能力
服務注冊接入本身分為兩個層面,一個是已有服務的注冊接入,一個是需要適配后的服務發布。在設計的時候需要考慮到兩個方面的需求。
對于已有服務的存代理接入最簡單,即只需要提供業務系統的 Rest 接口服務地址即可,在接入的時候,對相關的日志,安全,流控,負載均衡等策略進行配置,配置完成后即完成服務接入和注冊。同時對于路由服務接入需要單獨考慮,對于路由服務在接入的時候可以適配到多個原始業務系統的接口服務地址。
服務發布是對原來我們服務適配功能的一個改進,即直接從底向上的進行服務發布,而不需要實現定義服務元數據或模型,制定服務契約格式等,在服務發布完成后再生成相關的基礎數據到服務元數據庫即可。對于服務發布參考服務適配的能力,我們可以考慮如下場景下的需求。
將一個已有的 SOAP WS 服務發布和注冊為一個 Http Rest 接口服務。
將一個數據庫表,或存儲過程發布為一個 Http Rest 接口服務。
將一個 JMS 消息接口發布為一個 Http Rest 接口服務。
將一個 JAR 包中的 API 接口方法或函數發布為一個 Http Rest 接口服務。
對于服務發布而言,如果不僅僅是微服務網關能力,而是一個微服務支撐或微服務快速開發平臺的話,還可以提供完整的服務開發和設計能力。即在微服務平臺首先定義數據或對象模型,然后將對象模型轉換為 Http Rest 中的資源對象,并發布對應的 Get , Post 各種 Http Rest 接口服務。
對應發布的接口服務可以直接在微服務平臺上進行攔截,模擬生成相關的輸入或輸出數據。當然也可以直接將數據模型對象生成到對應的數據庫,同時將微服務 API 接口的實現生成對應的 Java 代碼框架并給出參考實現。而我們剩余的工作,僅僅是填充代碼邏輯即可。通過這種方式可以極大的提高我們進行微服務架構開發的速度。
API 接口在線模擬測試功能
這個功能參考當前的 OpenAPI 能力開放平臺的做法來實現即可。即對于已經發布完成的 API 接口服務,提供在線測試工具進行在線測試。同時對接口服務調用的輸入參數進行結構化展示,方便用戶對測試需要的各種參數進行輸入。在輸入完成后形成完整的提交參數完整字符串。通過測試,可以返回最終的模擬調用返回結果字符串信息。
同樣,這里可以采用 Swagger 工具來完成,Swagger 不僅僅是 API 接口的定義,接口文檔的生成,同時還可以根據可以接口定義,自動生成接口測試用例,對接口進行測試工作。我們也很容易將 Swagger 能力整合都 API 網關的管理平臺中。
API 接口查詢功能
對于 API 接口查詢功能也是一個標準的功能,實際上可以考慮將查詢功能和 API 接口服務的分類瀏覽分開。對于 API 接口的分類瀏覽參考開放平臺的 API 接口文檔做法來實現接口。對于 API 接口查詢,即可以設置不同的動態查詢條件,對 API 接口進行查詢,返回結果集。對于查詢到的 API 接口清單列表,可以點擊詳細進入到 API 接口詳細的輸入和輸出信息查看界面。
API 狀態管理功能
對于已經注冊和發布的 API 接口可以對其狀態進行管理。其中主要的狀態包括了待發布,上線,暫停,下線廢棄等幾種關鍵狀態。對于 API 狀態本身還需要和后續的 API 監控管理結合,能夠通過 API 性能監控動態的調整 API 接口的狀態。比如在 API 觸發熔斷后,自動對 API 接口狀態調整為暫停。
API 版本管理能力
對于 API 需要啟用版本管理能力。當前一些 API 接口服務實現方法會在路徑參數中增加 API 版本信息,以確定究竟訪問哪個版本。但是由于不同的 API 版本可能存在返回的結果集的數據結構不一樣的問題,因此對于這種場景需要針對該 API 定義不同的大版本,不同的大版本實際上對應不同的后端原始服務。
在這里我們介紹下當前主流的一些 API 網關功能供參考。
開源 Kong API 網關
在微服務架構之下,服務被拆的非常零散,降低了耦合度的同時也給服務的統一管理增加了難度。如上圖左所示,在舊的服務治理體系之下,鑒權,限流,日志,監控等通用功能需要在每個服務中單獨實現,這使得系統維護者沒有一個全局的視圖來統一管理這些功能。API 網關致力于解決的問題便是為微服務納管這些通用的功能,在此基礎上提高系統的可擴展性。
Kong 的插件機制是其高可擴展性的根源,Kong 可以很方便地為路由和服務提供各種插件,網關所需要的基本特性,Kong 都如數支持:
云原生: 與平臺無關,Kong 可以從裸機運行到 Kubernetes
動態路由:Kong 的背后是 OpenResty+Lua,所以繼承了動態路由的特性
限流和熔斷
健康檢查
日志: 可以記錄通過 Kong 的 HTTP,TCP,UDP 請求和響應。
鑒權: 權限控制,IP 黑白名單,同樣是 OpenResty 的特性
SSL: Setup a Specific SSL Certificate for an underlying service or API.
監控: Kong 提供了實時監控插件
認證: 如數支持 HMAC, JWT, Basic, OAuth2.0 等常用協議
REST API: 通過 Rest API 進行配置管理,從繁瑣的配置文件中解放
可用性: 天然支持分布式
高性能: 背靠非阻塞通信的 nginx,性能自不用說
插件機制: 提供眾多開箱即用的插件,且有易于擴展的自定義插件接口
從上面圖可以看到,Kong 網關是基于 OpenResty 應用服務器,OpenResty 是一個基于 Nginx 與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。用于方便地搭建能夠處理超高并發、擴展性極高的動態 Web 應用、Web 服務和動態網關。而 Kong 核心基于 OpenResty 構建,并且擁有強大的插件擴展功能。
在 Http 請求到達 Kong 網關后,轉發給后端應用之前,可以通過網關的各種插件對請求進行流量控制,安全,日志等各方面的處理能力。當前 Kong 的插件分為開源版和社區版,社區版還有更多的定制功能,但是社區版是要收費的。
目前,KONG 開源版本一共開放 28 個插件,如下:
acl、aws-lambda、basic-auth、bot-detection、correlation-id、cors、datadog、file-log、galileo、hmac-auth、http-log、ip-restriction、jwt、key-auth、ldap-auth、loggly、oauth2、rate-limiting、request-size-limiting、request-termination、request-transformer、response-ratelimiting、response-transformer、runscope、statsd、syslog、tcp-log、udp-log。
以上這些插件主要分五大類,Authentication 認證,Security 安全,Traffic Control 流量控制,Analytics & Monitoring 分析&監控,Logging 日志,其他還有請求報文處理類。插件類似 AOP 開發中的橫切功能,可以靈活的配置進行攔截控制,下面選擇一些關鍵性的插件進行簡單的說明。
黑白名單控制能力-ip-restriction
Kong 提供的 IP 黑白名單控制能力還算相當強,從配置項里面可以看到主要可以針對兩個維度進行配置,一個是針對所有的 API 接口還是針對特定的 API 接口,一個是針對所有的所有的消費方還是特定的某個消費方。對于 IP 配置可以是一個區段,也可以是特定的 IP 地址。但是黑白名單不能同時配置,其次當前沒有一個功能是針對某一個系統提供的所有服務都啟用黑名單或白名單功能。
日志記錄能力-syslog, file-log,http-log
這里主要日志的插件比較多,一個是 sysLog 在配置后可以直接將 Kong 產生的日志寫入到應用服務器的系統日志文件中。如果配置了 file-log 則是單獨寫入到你指定的 file 文件中。對于 http-log 則是對于 http 服務請求,可以詳細的記錄請求的輸入和輸出報文信息,但是具體是記錄到哪里,需要通過 config.http_endpoint 配置。具體關鍵的配置參數信息如下:
consumer_id: 可選參數,消費者 id(啟用了消費者認證可以使用,根據 id 識別發出請求的消費者);
config.http_endpoint: 日志接收服務器(包括使用的協議,http or https);
config.method: 可選參數,默認 POST,訪問日志服務器的請求方式(可選值:PUT,PATCH,POST);
config.timeout: 可選參數,默認 10000 毫秒,請求超時時間
config.keepalive: 可選參數,默認 60000 毫秒,連接在關閉之前可存活時間
熔斷插件-request-termination
該插件用來定義指定請求或服務不進行上層服務,而直接返回指定的內容.用來為指定的請求或指定的服務進行熔斷。注意 Kong 的熔斷插件感覺是臨時對服務的禁用,而不是說當達到某一種監控閾值的時候自動觸發熔斷,或者相關內容還沒有了解到。從官方文檔的應用場景也可以看到這點。
Temporarily disable a Service (e.g. it is under maintenance).
Temporarily disable a Route (e.g. the rest of the Service is up and running, but a particular endpoint must be disabled).
Temporarily disable a Consumer (e.g. excessive consumption).
如果僅僅是這種方式的熔斷話,實際上意義并不是很大。但是可用的地方就在于當某個業務系統進行發版部署的時候我們可以對該業務系統或該業務系統所提供的所有服務進行熔斷。
限流插件-rate-limiting
Kong 當前提供的限流相對來說還是比較弱,即主要是控制某一個 API 接口服務在單位時間內最多只能夠調用多少次,如果超過這個次數那么網關就直接拒絕訪問并返回錯誤提示信息。而在前面我講限流和流量控制的時候經常會說到,就是限流實際上一個是根據服務調用次數,一個是根據服務調用數據量,需要在這兩個方面進行限流。而里面更加重要的反而是數據量的限流,因為大數據量報文往往更加容易造成內存溢出異常。
安全認證類插件
當前 Kong 網關提供 basic-auth,key-auth、ldap-auth,hmac-auth 多種認證插件。
Basic-auth 基本認證插件,即我們根據用戶名和密碼來生成一個 base64 編碼,同時將該編碼和目標服務綁定,這樣在消費目標服務的時候就需要在報文頭填寫這個 Base64 編碼信息。
Key-auth 認證插件則是利用提前預設好的關鍵字名稱,如下面設置的 keynote = apices,然后為 consumer 設置一個 key-auth 密鑰,假如 key-auth=test@keyauth。在請求 api 的時候,將 apikey=test@keyauth,作為一個參數附加到請求 url 后,或者放置到 headers 中。
Hmac-auth 插件是設置綁定的 service 和 rout,以啟動 hmac 驗證。然后在 Consumers 頁面中 Hmac credentials of Consumer 設置中添加一個 username 和 secret。
請求報文容量限制-request-size-limiting
該插件用于限制請求報文的數據量大小,可以限制單個服務,也可以顯示所有的 API 接口服務。
支持 OAuth2.0 身份認證-oauth2
Kong 網關支持 OAuth2.0 身份認證,OAuth2.0 協議根據使用不同的適用場景,定義了用于四種授權模式。
Authorization code(授權碼模式):標準的 Server 授權模式,非常適合 Server 端的 Web 應用。一旦資源的擁有者授權訪問他們的數據之后,他們將會被重定向到 Web 應用并在 URL 的查詢參數中附帶一個授權碼(code)。在客戶端里,該 code 用于請求訪問令牌(access_token)。并且該令牌交換的過程是兩個服務端之前完成的,防止其他人甚至是資源擁有者本人得到該令牌。另外,在該授權模式下可以通過 refresh_token 來刷新令牌以延長訪問授權時間,也是最為復雜的一種方式。
Implicit Grant(隱式模式):該模式是所有授權模式中最簡單的一種,并為運行于瀏覽器中的腳本應用做了優化。當用戶訪問該應用時,服務端會立即生成一個新的訪問令牌(access_token)并通過 URL 的#hash 傳回客戶端。這時,客戶端就可以利用 JavaScript 等將其取出然后請求 API 接口。該模式不需要授權碼(code),當然也不會提供 refresh token 以獲得長期訪問的入口。
Resource Owner Password Credentials(密碼模式):自己有一套用戶體系,這種模式要求用戶提供用戶名和密碼來交換訪問令牌(access_token)。該模式僅用于非常值得信任的用戶,例如 API 提供者本人所寫的移動應用。雖然用戶也要求提供密碼,但并不需要存儲在設備上。因為初始驗證之后,只需將 OAuth 的令牌記錄下來即可。如果用戶希望取消授權,因為其真實密碼并沒有被記錄,因此無需修改密碼就可以立即取消授權。token 本身也只是得到有限的授權,因此相比最傳統的 username/password 授權,該模式依然更為安全。
Client Credentials(客戶端模式):沒有用戶的概念,一種基于 APP 的密鑰直接進行授權,因此 APP 的權限非常大。它適合像數據庫或存儲服務器這種對 API 的訪問需求。
簡單轉換能力-request-transformer and response transformer
Kong 網關提供對輸入和輸出報文簡單轉換的能力,這部分內容后續再詳細展開介紹。從當前配置來看,主要是對消息報文提供了 Add, Replace,Rename,Append 等各種簡單操作能力。
Kong 網關和其它網關的一些對比。
從上面對比圖也可以看到,Kong 網關在功能,性能,插件可擴展性各方面都能夠更好的滿足企業 API 網關的需求。因此我們也是基于 Konga 來進一步定制對 Kong 網關的管控治理平臺。
在整個定制中增加了基于 DB 適配的 Http Rest API 接口的自動發布,API 服務自動化注冊,服務日志采集和服務日志查詢,常見映射模板定制,接口服務的自動化測試等方面的能力。
阿里公有云 API 網關
首先我們來看下阿里云提供的 API 網關產品的功能介紹:
API 網關(API Gateway),是提供 API 托管服務,涵蓋 API 發布、管理、運維、售賣的全生命周期管理。輔助用戶簡單、快速、低成本、低風險的實現微服務聚合、前后端分離、系統集成,向合作伙伴、開發者開放功能和數據。
阿里提供的 API 網關提供的關鍵功能,參考產品本身的功能文檔說明,主要如下:
API 生命周期管理
支持包括 API 注冊和接入發布、API 測試、API 下線等生命周期管理功能。支持 API 日常管理、API 版本管理、API 快速回滾等維護功能。基本需要覆蓋 API 管理全生命周期。
全面的安全防護
支持多種認證方式,支持 HMAC (SHA-1,SHA-256) 算法簽名。支持 HTTPS 協議,支持 SSL 加密。防攻擊、防注入、請求防重放、請求防篡改。(沒看到是否支持 Auth2.0 和具體的 Token 驗證機制)
靈活的權限控制
用戶以 APP 作為請求 API 的身份,網關支持針對 APP 的權限控制。只有已經獲得授權的 APP 才能請求相應的 API。API 提供者可以將調用某個 API 的權限主動授予給某個 APP。若 API 上架到 API 市場,購買者可以將已購買的 API 授權給自己的 APP。(沒看到是否基于 IP 進行控制,還是基于 Token 進行控制,即對于消費方分配獨立的 Token 信息)
精準的流量控制
流量控制可以用于管控 API 的被訪問頻率、APP 的請求頻率、用戶的請求頻率。流量控制的時間單位可以是分鐘、小時、天。支持流控例外,允許設置特殊的 APP 或者用戶。(流量控制只支持服務運行頻率,沒看到可以基于數據量進行流控)
請求校驗
支持參數類型、參數值(范圍、枚舉、正則、Json Schema)校驗,無效校驗會被 API 網關直接拒絕,以減少無效請求對后端造成的資源浪費,大幅降低后端服務的處理成本。(這個功能實際有一定的用處,并不會犧牲太多的性能,但是會實現一些簡單的參數完整性校驗能力。)
數據轉換
通過配置映射規則,實現前、后端數據翻譯。支持前端請求的數據轉換。支持返回結果的數據轉換。(暫時不清楚數據轉換功能能夠實現的能力)
監控報警
提供可視化的 API 實時監控,包括:調用量、流量大小、響應時間、錯誤率,在陸續增加維度。支持歷史情況查詢,以便統籌分析。可配置預警方式(短信、Email),訂閱預警信息,以便實時掌握 API 運行情況。
自動工具
自動生成 API 文檔,可供在線查看。API 網關提供多種語言 SDK 的示例。降低 API 的運維成本。提供可視化的界面調試工具,快速測試,快速上線。(當前網上也有不少的 API 接口文檔自動生成工具可選)
API 市場
可將 API 上架到 API 市場,供更多開發者采購和使用。
從整個功能的介紹可以看到對于 API 的全生命周期管理(注冊,接入,代理,路由,負載均衡),安全,權限,流量控制,監控和告警等是所有 API 網關都必須具備的功能。而對于 API 市場,API 文檔自動生成,請求的參數校驗,數據的轉換等則可以看做是擴展功能。
對于 API 市場往往是一個重要的擴展能力,即對于 API 接口服務可以作為商品一樣進行訂購和使用,并根據相應的調用次數,調用的數據量等條件進行計費處理。這我們我們說的 PaaS 平臺的服務層能力作為產品和服務發布,能夠進行訂購生產訂單,能夠進行計費等完全是一個道理。
對于公有云上 API 網關存在的背景說明
對于類似亞馬遜,華為云,阿里云等公有云上為何要提供 API 網關類產品,其關鍵點還是在于一個企業如果內部的主動業務應用和系統都遷移到公有云后,那么當企業需要將內部多個業務系統的共享或發布給外部使用的時候如何做?這個時候必須要有一個 API 網關,來進行能力的統一發布,最基本是提供統一的服務目錄訪問,更加重要的是實現統一的安全管理,授權,服務日志監控預警能力。
因此一個企業遷移到公有云后,只要存在內部多業務系統,多組件都需要發布 API 接口能力給外部使用的時候,一定存在 API 網關的應用場景。
其它開源 API 網關
有贊團隊的 API 網關實踐
https://tech.youzan.com/api-gateway-in-practice/
有贊 API 網關目前承載著微商城、零售、微小店、餐飲、美業、AppSDK、部分 PC、三方開發者等多個業務的調用,每天有著億級別的流量。
有贊后端服務最開始是由 PHP 搭建,隨著整個技術體系的升級,后面逐步從 PHP 遷移到基于 Dubbo 開發了一個新的框架 Nova,兼容 Dubbo 調用,同時支持調用 PHP 服務。于是網關也支持了新的 Nova 協議,這樣就有 Dubbo、Http、Nova 三種協議。
在這篇文章中提到的網關核心設計部分相關內容可以參考
異步特性:我們使用 Jetty 容器來部署應用,并開啟 Servlet3.0 的異步特性,由于網關業務本身就是調用大量業務接口,因此 IO 操作會比較頻繁,使用該特性能較大提升網關整體并發能力及吞吐量。
緩存:為了進一步提升網關的性能,我們增加了一層分布式緩存(借用 Codis 實現),將一些不經常變更的 API 元數據緩存下來,這樣不僅減少了應用和 DB 的交互次數,還加快了讀取效率。
鏈式處理:在設計網關的時候,我們采用責任鏈模式來實現網關的核心處理流程,將每個處理邏輯看成一個 Pipe,每個 Pipe 按照預先設定的順序先后執行
平滑限流:消除了簡單計數器限流帶來的短時間內流量不均的問題。目前網關支持 IP、店鋪、API、應用 ID 和三方 ID 等多個維度的限流,也支持各維度的自由組合限流。
熔斷降級:使用 Hystrix 進行熔斷降級處理。Hystrix 支持線程池和信號量 2 種模式的隔離方案,內部也開發了一個基于 Hystrix 的服務熔斷平臺
預警監控:實時地從 Kafka 消費 API 調用日志,如果發現某個 API 的 RT 或者錯誤次數超過配置的報警閾值,則會立即觸發報警
企業級 API 網關設計
https://cloud.tencent.com/developer/article/1080652
這篇文章是對企業級 API 網關設計必須系統化的產生,從 API 網關的概述,API 網關所起的作用,當前主流的 API 網關功能對比分析,API 網關的高可用性設計多方面進行了闡述。
網關層作為客戶端與服務端的一層擋板,主要起到了三大類作用:
隔離作用:作為企業系統邊界,隔離外網系統與內網系統。
解耦作用:通過解耦,使得微服務系統的各方能夠獨立、自由、高效、靈活地調整。
腳手架作用:提供了一個地點,方便通過擴展機制對請求進行一系列加工和處理。
API 網關作為對外提供服務的入口,就像企業服務的大門。一方面,要有足夠的能力,應對大量的對外訪問,另一方面,還要給對內的服務提供一定的安全保障。除此之外,企業提供的 API 服務多種多樣,API 網關要能夠對這些 API 的全生命周期進行便捷的管理,例如服務發布、調整、下架、計費、監控等。
企業 API 網關在功能設計上主要應該考慮如下內容:
API 生命周期管理功能:覆蓋 API 的定義、測試、發布的整個生命周期管理。
API 開發和使用支持功能:
安全防護功能:API 請求到達網關需要經過身份認證、權限認證,才能到達后端服務。
流量控制功能:API 調用次數,異常,分級。流控粒度:分鐘、小時、天。
請求管理功能:可根據配置進行參數類型、參數值(范圍、枚舉、正則)的校驗
監控告警功能:提供實時、可視化的 API 監控,調用量、調用方式、響應時間、錯誤率。
API 交易功能:提供 API 交易市場,計量計費、Quota 控制、運營售賣等需求。
順著這篇文章,我們參考了另外一篇談如何設計高并發下 API 網關的一篇文章,重點對并發模型,SEDA 基于事件的并發架構進行了闡述。
地址:https://mp.weixin.qq.com/s?__biz=MzI5MDEzMzg5Nw==&mid=412734308&idx=1&sn=f1c1bd5e22e2ae7dedf4b788a625e814&scene=21#wechat_redirect
傳統的并發編程模型主要有兩種:一種是 Thread-based concurrency, 另一種是 Event-driven concurrency。總結下兩種模式的特點如下:
基于線程的并發:每個任務一線程直線式的編程使用資源高昂,context 切換代價高,競爭鎖昂貴,太多線程可能導致吞吐量下降,響應時間暴漲;
基于事件的并發:單線程處理事件的每個并發流實現為一個有限狀態機應用直接控制并發負載增加的時候,吞吐量飽和響應時間線性增長。
SEDA 架構是目前云計算、微服務時代下一種優秀的消息處理架構,而且歷經考驗,穩定可靠。SEDA 架構的核心思想:把一個請求處理過程分成幾個 Stage,每個 Stage 可由不同的微服務進行處理,不同資源消耗的 Stage 使用不同數量的線程來處理,微服務之間采用異步通訊的模式。
開源 API 網關 Goku
GoKu API Gateway,中文名:悟空 API 網關,是 eoLinker 旗下、國內首個企業級開源的 go 語言 API 網關,幫助企業進行 API 服務治理與 API 性能安全維護,為企業數字化賦能。
GoKu 支持 OpenAPI 與微服務管理,支持私有云部署,實現 API 轉發、請求參數轉換、數據校驗等功能,提供圖形化界面管理,能夠快速管理多個 API 網關,提高 API 業務安全性。
碼云地址:https://gitee.com/eolinker/goku-api-gateway
官網地址:https://www.eolinker.com/product/api_gateway/
Goku API Gateway (悟空 API 網關)是運行在企業系統服務邊界上的微服務網關。當您構建網站、App、IOT 甚至是開放 API 交易時,Goku API Gateway 能夠幫你將內部系統中重復的組件抽取出來并放置在 Goku 網關上運行,如進行用戶授權、訪問控制、防火墻、數據轉換等;并且 Goku 提供服務編排的功能,讓企業可以快速從各類服務上獲取需要的數據,對業務實現快速響應。
Goku API Gateway 的社區版本(CE)擁有完善的使用指南和二次開發指南,代碼使用純 Go 語言編寫,擁有良好的性能和擴展性,并且內置的插件系統能夠讓企業針對自身業務進行定制開發。并且 Goku API Gateway 支持與 EOLINKER 旗下的 API Studio 接口管理平臺結合,對 API 進行全面的管理、自動化測試、監控和運維。
產品關鍵特性
控制臺:通過清晰的 UI 界面對網關集群進行各項配置。
集群管理:Goku 網關節點是無狀態的,配置信息自動同步,支持節點水平拓展和多集群部署。
熱更新:無需重啟服務,即可持續更新配置和插件。
服務編排:一個編排 API 對應多個 backend,backend 的入參支持客戶端傳入,也支持 backend 間的參數傳遞;backend 的返回數據支持字段的過濾、刪除、移動、重命名、拆包和封包;編排 API 能夠設定編排調用失敗時的異常返回。
數據轉換:支持將返回數據轉換成 JSON 或 XML。
負載均衡:支持有權重的 round-robin 負載平衡。
服務發現:從 Consul、Eureka 等注冊中心發現后端服務器。
HTTP(S)反向代理:隱藏真實后端服務,支持 Rest API、Webservice。
多租戶管理:根據不同的訪問終端或用戶來判斷。
訪問策略:支持不同策略訪問不同的 API、配置不同的鑒權(匿名、Apikey、Basic)等。
靈活的轉發規則:支持模糊匹配請求路徑,支持改寫轉發路徑等,可為不同訪問策略或集群設置不同的負載。
IP 黑白名單。
自定義插件:允許插件掛載在常見階段,例如 before match,access 和 proxy。
CLI: 使用命令行來啟動、關閉和重啟 Goku。
Serverless: 在轉發過程的每一個階段,都可以添加并調用自定義的插件。
請求日志(access log):僅記錄轉發的基本內容,自定義記錄字段與排序順序,定期自動清理日志。
運行日志(system log):提供控制臺和節點的運行日志,默認僅記錄 ERROR 等級的信息,可將等級按實際情況調成 INFO、WARN 或 DEBUG。
可擴展:簡單易用的插件機制方便擴展功能。
高性能:性能在眾多網關之中表現優異。
Open API:提供 API 對網關進行操作,便于集成。
版本控制:支持操作的發布和多次回滾。
監控和指標:支持 Prometheus、Graphite。
具體對比:https://help.eolinker.com/#/tutorial/?groupID=c-269&productID=19
從對比可以看到,開源版本對于關鍵的服務限流熔斷,服務降級,數據緩存,格式轉換,請求大小校驗等能力是沒有的,這些能力只在企業版本中提供。
由于該網關基于 Go 語言編寫,因此比類似 Zuul 網關有更好的性能,實際性能測試結果數據來看,和 Kong 網關的性能比較接近,比 Kong 網關性能略好。
關鍵內容說明
整個部署架構圖和常見的 ESB 總線或 API 網關產品類似,數據庫可以采用 Oracle 或 Mysql 數據庫,緩存采用 Redis 庫進行緩存。前端通過 F5 或 Ngnix 進行負載均衡,本身網關節點是無狀態的,支持集群化架構部署。
通過定期檢查后端服務器的可用情況,智能識別可用后端、屏蔽不可用后端,減少服務器開銷。這個實際類似對后端的業務服務進行心跳監測,出現問題后進行屏蔽或預警,后端服務不可用時候實際通過 API 網關封裝暴露的新代理服務本身也處于不可用狀態。
對于后端的業務服務本身可以再通過類似 Ngnix 集群或 K8s 集群暴露集群 IP 地址接入,當然網關本身也支持直接將多個后端業務多節點接入到網關中,由網關對后端業務服務器階段進行負載均衡,在采用了類似容器化和 K8s 或集群架構的后端來說,該功能往往并不會用到。
API 健康檢查,文檔編寫完成之后,API 定期檢查節點運行狀態,若節點出現異常則通過郵件或者 API 發送告警信息,并自動嘗試重啟修復節點。實際我們看到對于 API 的監控檢查包括了兩個方面,一個是通過網關封裝后的 API 節點的監控檢查,一個是后端業務 API 服務的監控檢查。
API 斷線重連:請求轉發失敗后,網關會進行一定次數的斷線重連,防止因網絡閃斷等原因導致 API 訪問質量下降。這個類似我們說的服務重試機制,傳統 ESB 總線的標準能力。該功能還是有用,主要是為了防止網絡閃斷引起的服務訪問異常。
在網關里可以給不同的調用方或客戶端設置訪問策略,不同的訪問策略可以設置不同的 API 訪問權限、鑒權方式以及插件功能等。網關支持 開放策略 與 普通策略:
開放策略:系統自帶訪問策略,使用開放策略時不需要傳遞策略 ID 參數;
普通策略:自定義訪問策略,需要傳遞策略 ID 參數。
網關的插件分為 策略插件 與 API 插件。
策略插件包括:流量控制、鑒權、IP 黑白名單等。API 插件包括:參數映射、額外參數、熔斷、服務降級等。鑒權的對象為 策略 (Strategy) ,策略可表示為一個公司、一個業務部門或一個用戶。開源版網關支持以下鑒權方式:Public、Basic、Apikey。暫時沒有看到基于消費訪問 IP 地址的服務訪問鑒權,不清楚是否企業版有對應的 IP 認證鑒權支持。
日志管理能力
網關系統的日志分為兩大部分:請求日志(access.log)和系統運行時日志;運行時日志又分為:控制臺的運行日志(console.log)、各節點的運行日志(node.log)。對于請求日志可以詳細的配置日志存放路徑,記錄周期,具體記錄的內容等。
整體相對來說,當前網關提供的日志管理能夠偏弱,特別是日志信息的查看,基于服務日志運行進行的 API 接口服務的運行分析統計等方面的能力。
參數映射:功能具備,但是使用起來會比較麻煩,暫時沒看到圖形化或者表格方式的參數映射界面。對于參數映射不一定完全的圖形化,但是提供類似阿里云 API 網關的表格化映射是一種可行的方式。
小豹 API 網關
http://www.xbgateway.com/architecture.html
這個是最近在網上查找 API 網關相關資料的時候搜索到的一個商用的 API 網關,從產品介紹材料來看,我們前面談過的網關的核心功能基本上全部包括,而且相當來說也比較完善。同時提供了一個較方便的 API 網關的治理管控平臺,可以方便的對 API 注冊接入和運行全生命周期, 方便對安全,流控,日志各方面進行靈活管控。
下面我們看下網站對 API 網關架構特點的一些說明:
基于 Netty NIO 的響應式架構;分布式緩存基于 Redis;數據庫基于 Mysql,分布式配置基于 ZooKeeper
API 配置緩存,運行時不依賴 DB,配置更新后自動通知各網關節點;
支持自定義組件,動態加載,在不中斷網關服務的情況下重新加載配置和運行組件;
API 服務連續異常后自動熔斷和自我恢復,訪問異常、超時處理;
網關核心運行過程不寫磁盤 IO,避免磁盤 IO 性能影響網關吞吐量;
Docker 容器化支持,拆分網關、管理服務、第三方中間件依賴等鏡像,便于靈活擴容。
RestCloud API 企業微服務 API 開發
http://www.restcloud.cn/restcloud/mycms/apigateway.html
RestCloud API 網關是完全自主研發的面向企業級的 API 網關,一且以簡單、易用、輕量級為目標進行研發,同時兼顧作為企業級的服務總線可以替換企業原有的 ESB 產品,RestCloud 是集 ESB 和 API 網關于一體的企業級網關產品。這個不僅僅提供了 API 網關, 也提供了微服務快速開發平臺,API 服務治理平臺,DaaS 等相關組件。
另外 RestCloud 本身還提供了 Http Rest API 接口的快速開發平臺,可以將數據庫表,表對象,1 多多對象關系的快速的發布為 Http Rest API 接口服務,同時支持多數據庫接口適配。
最后,再附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,筆者這幾年及春招的總結,github 1.4k star,拿去不謝!
下載方式1.?首先掃描下方二維碼 2.?后臺回復「Java面試」即可獲取總結
以上是生活随笔為你收集整理的万字讲解API网关的来龙去脉的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用华为鸿蒙 OS 2.0 系统写出了He
- 下一篇: 4次迭代!10w行级别数据的Excel导