[轉載]選擇Kong作為你的API網關

更新,現在有更強大的API網關,國產 Apache APISIX,可自行谷歌。

本文轉載自選擇Kong作為你的API網關

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

為什么需要 API 網關

在微服務架構之下,服務被拆的非常零散,降低了耦合度的同時也給服務的統一管理增加了難度。如上圖左所示,在舊的服務治理體系之下,鑒權,限流,日志,監控等通用功能需要在每個服務中單獨實現,這使得系統維護者沒有一個全局的視圖來統一管理這些功能。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 可以認為是一個 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 對外暴露了 Restful API,最終的配置便是落地在了數據庫之中。

Kong 的管理方式

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

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

kong端點

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

一個典型的 Nginx 配置

upstream helloUpstream {
  server localhost:3000 weight=100;
}

server {
  listen  80;
  location /hello {
      proxy_pass http://helloUpstream;
  }
}

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

對應的 Kong 配置

# 配置 upstream
curl -X POST http://localhost:8001/upstreams --data "name=helloUpstream"
# 配置 target
curl -X POST http://localhost:8001/upstreams/hello/targets --data "target=localhost:3000" --data "weight=100"
# 配置 service
curl -X POST http://localhost:8001/services --data "name=hello" --data "host=helloUpstream"
# 配置 route
curl -X POST http://localhost:8001/routes --data "paths[]=/hello" --data "service.id=8695cc65-16c1-43b1-95a1-5d30d0a50409"
curl -X POST http://localhost:8001/routes --data "hosts[]=a.com,b.com,*.abc.com" --data "service.id=8695cc65-16c1-43b1-95a1-5d30d0a50409"

這一切都是動態的,無需手動 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次/秒的限流

curl -X POST http://localhost:8001/services/hello/plugins \
--data "name=rate-limiting" \
--data "config.second=50"

為 hello 服務添加 jwt 插件

curl -X POST http://localhost:8001/services/login/plugins \
--data "name=jwt"

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

curl -X POST http://localhost:8001/routes/{routeId}/plugins \
--data "name=rate-limiting" \
--data "config.second=50"

curl -X POST http://localhost:8001/routes/{routeId}/plugins \
--data "name=jwt"

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

總結

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


閱讀擴展

初識 Kong 之負載均衡 https://www.cnkirito.moe/kong-loadbalance/

Kong 集成 Jwt 插件 https://www.cnkirito.moe/kong-jwt/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內容