==================================
為什么需要API gateway?
==================================
企業后台微服務互聯互通, 因為在內網, 安全基本沒問題, 再配合使用Basic Auth就足夠了, 同時也能利用上服務注冊的優點, 有效隔離微服務之間的相互依賴. 但如果通過javascript/原生app直接訪問微服務, 就會有下面的問題:
1. 接口安全問題, 很容易就能查看到js調用微服務api的代碼, api肯定不能再裸奔, 需要加入安全檢查機制. 每個微服務都要加同樣的安全機制, 重復工作量很大.
2. 網絡安全問題, 我們不應該將所有的微服務機器都暴露到外網, 網絡風險較大.
3. 前后端耦合問題, 在調用api時候, 必須寫死微服務ip信息, 如果微服務IP有變動, 前端也要及時更改才行.
4. 容易有單點問題, js 無法利用服務注冊機制, 必須寫死一個微服務主機ip, 即使我們的微服務往往會部署多套, 也有單點問題.
引入 api 網關就是要解決上述問題, api 網關作為對外服務的 facade 層. 另外, api 網關還可以實現智能路由功能, 以及動態擴容縮容, 甚至上可以聚合一些微服務操作, 以減少網絡交互次數, 改善用戶體驗, 這個 ESB 的作用類似, 當然要謹慎使用, 比如體量較大的To C應用, 如果提供web/手機不同的訪問形式, 可以考慮使用這一優化手段.
API 網關的管理范圍:
1. 僅僅管理API訪問(無狀態的那部分), 並不負責管理普通web服務器.
2. 僅僅管理對外服務的API, 不負責微服務內部的數據請求, 如果要將微服務內部通訊管起來, API 網關的網絡壓力太大, 會是性能的瓶頸.
API 網關使用場景:
1. 開放平台, 比如微信或微博的開放平台, 這樣的平台是專門針對第三方應用接入的, 提供 API 接入是最優選擇.
2. 支持大型原生app, 大型原生app后台需要很多微服務項目, 通過 api 網關和這些微服務對接是比較方便的.
3. 網頁js埋點采集, 埋點采集api不需要關心權限, 引入api網關主要是利用其自動擴容特性, 比如引入kong.
下圖是引入 api 網關后的架構圖(不含 WebUI 項目)
==================================
企業內部微服務架構有必要引入 API gateway 嗎?
==================================
企業內部一般情況是: 僅僅有web應用, 沒有移動端應用, 所有的用戶都在局域網內部.
針對這樣的情形, 我認為引入 API 網關的意義並不大, 理由是: web 項目肯定會有一個Web 后台應用服務器, 后台應用服務器可以承擔api網關的主要職責, 包括api流量轉發和安全檢查.
簡答一個常見的疑問:
典型 web 項目的 UI 往往是由后端模板渲染+前端ajax調用api組成. 后端模板肯定是本應用的web 后台提供, 但ajax調用的api是本應用后台提供, 還是其他微服務項目提供呢?
我的答案是: ajax調用的api最好還是本應用的web后台提供, 這樣 jquery 和 api 屬於同域, ajax 請求會自動帶上本域的cookie, 這台web服務器本身也有相應的 session 信息, 所以ajax請求能通過 session-cookie 完成身份驗證, 整個過程非常自然. 如果 ajax調用的api 是另一個微服務提供的, 為了保證微服務無狀態特性, 同時避免api不會被濫用, 需要完善方案, 可選方案如下:
1. 在微服務項目中引入 redis集群來共享session存儲, 將狀態轉移到redis集群中. 這個方案比較重, 並且 jquery 和 微服務不是同源, 需要在ajax調用時加上cookie, 可參考: https://blog.csdn.net/wzl002/article/details/51441704
2. 微服務項目不使用session做身份驗證, 而是引入 jwt. 本方案的缺點: 想想有那么多的微服務項目都要加上jwt機制, 肯定比較麻煩, 另外js 調用微服務的url, 無法利用上服務注冊的好處.
3. 引入api 網關, 將jwt身份驗證前移到api網關層. 該方案能避免方案2的缺點, 但因為引入了新的一層, 整體架構變得復雜了.
下圖是一個基於微服務的 WebUI 項目架構圖,
==================================
API 網關的選型
==================================
常用的API網關候選, 主要有 Kong/Netflix Zuul/Spring Cloud Gateway, 詳見下面博客
https://www.cnblogs.com/savorboard/p/api-gateway.html
Kong 是一個非常優秀的開源 API 網關產品, 基於 OpenResty + Cassandra/PostgreSQL, 以插件的形式提供很多功能(身份認證/權限控制/日志/流量控制), 也可以使用 Lua 編寫插件, 底層是 Nginx , 所以性能非常好, 社區插件也較多, 但要定制插件難度較大, 需要使用 Lua 編寫.
Spring 社區主要是 Netflix Zuul 和 Spring Cloud Gateway, Netflix Zuul 是基於Servlet 2.5, 使用阻塞 API, 它不支持任何長連接, 如 WebSocket. Spring Cloud Gateway 是Spring社區主推的解決方案, 采用了更新的技術, 它基於Spring framework 5, Project Rector 和 Spring Boot 2, 使用的是非阻塞API, 支持 Websocket.
對於企業內應用, 研發主導的話推薦是使用 Spring Cloud Gateway, 運維主導的話推薦 kong.
對於大型互聯網開放平台, 推薦性能更好的 kong.
買單俠微服務的API網關演化之路
https://blog.csdn.net/omnistack/article/details/77185188
https://blog.csdn.net/OmniStack/article/details/77881185
==================================
Spring Cloud Gateway 參考
==================================
Spring Cloud Gateway 入門
https://www.jianshu.com/p/598f302dadba
https://www.jianshu.com/p/76d2da1d0dd7
Spring Cloud(十三):Spring Cloud Gateway(路由)
https://windmt.com/tags/API-Gateway/
Spring Gateway配置使用(一)
https://www.jianshu.com/p/d011a0e5539d
Spring Cloud Gateway入門案例
https://www.jianshu.com/p/44a0d6adcdea
Spring Cloud(十八):Spring Cloud Gateway(讀取、修改 Request Body)
http://www.liuhaihua.cn/archives/549430.html