選擇Kong作為你的API網關

選擇Kong作為你的API網關


Kong(https://github.com/Kong/kong)是一個雲原生,高效,可擴展的分佈式 API 網關。 自 2015 年在 github 開源後,廣泛受到關注,目前已收穫 1.68w+ 的 star,其核心價值在於高性能和可擴展性。

為什麼需要 API 網關



選擇Kong作為你的API網關

img


在微服務架構之下,服務被拆的非常零散,降低了耦合度的同時也給服務的統一管理增加了難度。如上圖左所示,在舊的服務治理體系之下,鑑權,限流,日誌,監控等通用功能需要在每個服務中單獨實現,這使得系統維護者沒有一個全局的視圖來統一管理這些功能。API 網關致力於解決的問題便是為微服務納管這些通用的功能,在此基礎上提高系統的可擴展性。如右圖所示,微服務搭配上 API 網關,可以使得服務本身更專注於自己的領域,很好地對服務調用者和服務提供者做了隔離。

為什麼是 Kong


SpringCloud 玩家肯定都聽說過 Zuul 這個路由組件,包括 Zuul2 和 Springcloud Gateway 等框架,在國內的知名度都不低。沒錯,我稱呼這些為組件 Or 框架,而 Kong 則更襯的上產品這個詞。在此我們可以簡單對比下 Zuul 和 Kong。

舉例而言,如果選擇使用 Zuul,當需要為應用添加限流功能,由於 Zuul 只提供了基本的路由功能,開發者需要自己研發 Zuul Filter,可能你覺得一個功能還並不麻煩,但如果在此基礎上對 Zuul 提出更多的要求,很遺憾,Zuul 使用者需要自行承擔這些複雜性。而對於 Kong 來說,限流功能就是一個插件,只需要簡單的配置,即可開箱即用。

Kong 的插件機制是其高可擴展性的根源,Kong 可以很方便地為路由和服務提供各種插件,網關所需要的基本特性,Kong 都如數支持:

  • 雲原生: 與平臺無關,Kong可以從裸機運行到Kubernetes
  • 動態路由:Kong 的背後是 OpenResty+Lua,所以從 OpenResty 繼承了動態路由的特性
  • 熔斷
  • 健康檢查
  • 日誌: 可以記錄通過 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,性能自不用說
  • 插件機制: 提供眾多開箱即用的插件,且有易於擴展的自定義插件接口,用戶可以使用 Lua 自行開發插件

上面這些特性中,反覆提及了 Kong 背後的 OpenResty,實際上,使用 Kong 之後,Nginx 可以完全摒棄,Kong 的功能是 Nginx 的父集。

而 Zuul 除了基礎的路由特性以及其本身和 SpringCloud 結合較為緊密之外,並無任何優勢。

Kong 的架構



選擇Kong作為你的API網關

image-20180712184740981


從技術的角度講,Kong 可以認為是一個 OpenResty 應用程序。 OpenResty 運行在 Nginx 之上,使用 Lua 擴展了 Nginx。 Lua 是一種非常容易使用的腳本語言,可以讓你在 Nginx 中編寫一些邏輯操作。之前我們提到過一個概念 Kong = OpenResty + Nginx + Lua,但想要從全局視角瞭解 Kong 的工作原理,還是直接看源碼比較直接。我們定位到本地的 Kong 文件夾,按照上圖中的目錄層級來識識 Kong 的廬山真面目。

  1. Kong 文件下包含了全部源碼和必要組件,分析他們,我們便得到了 Kong 的架構。0.13.x 是目前 Kong 的最新版本。
  2. 從 2 號塊中可以看到 nginx.conf ,這其實便是一個標準的 Nginx 目錄結構,這也揭示了 Kong 其實就是運行在 Nginx 的基礎之上,而進行的二次封裝。由 share 文件夾向下展開下一次分析。
  3. share 文件夾中包含了 OpenResty 的相關內容,其實背後就是一堆 Lua 腳本,例如 lapis 包含了數據庫操作,Nginx 生命週期,緩存控制等必要的 Lua 腳本,logging 包含了日誌相關的 Lua 腳本,resty 包含了 dns,健康檢查等相關功能的 Lua 腳本…而其中的 kong 目錄值得我們重點分析,他包含了 Kong 的核心對象。
  4. api 和 core 文件夾,封裝了 Kong 對 service,route,upstream,target 等核心對象的操作代碼(這四個核心對象將會在下面的小節重點介紹),而 plugins 文件夾則是 Kong 高可擴展性的根源,存放了 kong 的諸多擴展功能。
  5. plugins 文件夾包含了上一節提到的 Kong 的諸多插件功能,如權限控制插件,跨域插件,jwt 插件,oauth2 插件…如果需要自定義插件,則需要將代碼置於此處。

從上述文件夾瀏覽下來,大概可以看到它和 Nginx 的相似之處,並在此基礎之上藉助於 Lua 對自身的功能進行了拓展,除了 nginx.conf 中的配置,和相對固定的文件層級,Kong 還需要連接一個數據庫來管理路由配置,服務配置,upstream 配置等信息,是的,由於 Kong 支持動態路由的特性,所以幾乎所有動態的配置都不是配置在文件中,而是藉助於 Postgres 或者 Cassandra 進行管理。

選擇Kong作為你的API網關

postgres


Kong 對外暴露了 Restful API,最終的配置便是落地在了數據庫之中。

Kong 的管理方式


通過文件夾結構的分析,以及數據庫中的表結構,我們已經對 Kong 的整體架構有了一個基本的認識,但肯定還存在一個疑問:我會配置 Nginx 來控制路由,但這個 Kong 應當怎麼配置才能達到相同的目的呢?莫急,下面來看看 Kong 如何管理配置。

Kong 簡單易用的背後,便是因為其所有的操作都是基於 HTTP Restful API 來進行的。

選擇Kong作為你的API網關

kong端點


其中 8000/8443 分別是 Http 和 Https 的轉發端口,等價於 Nginx 默認的 80 端口,而 8001 端口便是默認的管理端口,我們可以通過 HTTP Restful API 來動態管理 Kong 的配置。

一個典型的 Nginx 配置

選擇Kong作為你的API網關


如上這個簡單的 Nginx 配置,便可以轉換為如下的 Http 請求。

對應的 Kong 配置

選擇Kong作為你的API網關


這一切都是動態的,無需手動 reload nginx.conf。

我們為 Kong 新增路由信息時涉及到了 upstream,target,service,route 等概念,他們便是 Kong 最最核心的四個對象。(你可能在其他 Kong 的文章中見到了 api 這個對象,在最新版本 0.13 中已經被棄用,api 已經由 service 和 route 替代)

從上面的配置以及他們的字面含義大概能夠推測出他們的職責,upstream 是對上游服務器的抽象;target 代表了一個物理服務,是 ip + port 的抽象;service 是抽象層面的服務,他可以直接映射到一個物理服務(host 指向 ip + port),也可以指向一個 upstream 來做到負載均衡;route 是路由的抽象,他負責將實際的 request 映射到 service

他們的關係如下

upstream 和 target :1 對 n

service 和 upstream :1 對 1 或 1 對 0 (service 也可以直接指向具體的 target,相當於不做負載均衡)

service 和 route:1 對 n

高可擴展性的背後—插件機制


Kong 的另一大特色便是其插件機制,這也是我認為的 Kong 最優雅的一個設計。

文章開始時我們便提到一點,微服務架構中,網關應當承擔所有服務共同需要的那部分功能,這一節我們便來介紹下,Kong 如何添加 jwt 插件,限流插件。

插件(Plugins)裝在哪兒?對於部分插件,可能是全局的,影響範圍是整個 Kong 服務;大多數插件都是裝在 service 或者 route 之上。這使得插件的影響範圍非常靈活,我們可能只需要對核心接口進行限流控制,只需要對部分接口進行權限控制,這時候,對特定的 service 和 route 進行定向的配置即可。

為 hello 服務添加50次/秒的限流

選擇Kong作為你的API網關


為 hello 服務添加 jwt 插件

選擇Kong作為你的API網關


同理,插件也可以安裝在 route 之上

選擇Kong作為你的API網關


在官方文檔中,我們可以獲取全部的插件 https://konghq.com/plugins/,部分插件需要收費的企業版才可使用。

選擇Kong作為你的API網關

kong插件


總結


Kong 是目前市場上相對較為成熟的開源 API 網關產品,無論是性能,擴展性,還是功能特性,都決定了它是一款優秀的產品,對 OpenResty 和 Lua 感興趣的同學,Kong 也是一個優秀的學習參考對象。基於 OpenResty,可以在現有 Kong 的基礎上進行一些擴展,從而實現更復雜的特性,比如我司內部的 ABTest 插件和定製化的認證插件,開發成本都相對較低。Kong 系列的文章將會在以後持續連載。

作者:徐靖峰

來源:https://www.cnkirito.moe/kong-introduction/

相關推薦

推薦中...