API 網關的選型和持續集成

2019 年 8 月 31 日,OpenResty 社區聯合又拍雲,舉辦 OpenResty × Open Talk 全國巡迴沙龍·成都站,APISIX 做者溫銘在活動上作了《 API 網關的選型和持續集成 》的分享。html

OpenResty x Open Talk 全國巡迴沙龍是由 OpenResty 中國社區、又拍雲發起,邀請業內資深的 OpenResty 技術專家,分享 OpenResty 實戰經驗,增進 OpenResty 使用者的交流與學習,推進 OpenResty 開源項目的發展。前端

溫銘,深圳支流科技聯合創始人,開源微服務 API 網關 APISIX PMC,OpenResty軟件基金會發起人,《OpenResty 從入門到實戰》專欄做者,創業以前在互聯網安全公司工做了 10 年,主要從事服務端的開發和架構,負責開發過木馬雲查殺、反釣魚系統和企業安全產品。曾在奇虎 360 擔任架構師,開源委員會發起人、委員。vue

如下是分享全文:nginx

我和院生在作的一個開源的 API 網關項目叫 APISIX,今天介紹這個項目涉及到 OpenResty 的技術和選型,主要包括三個方面:數據庫

  • 第一, API 網關是什麼,它有什麼做用;
  • 第二,如何去作 API 網關,如何作選型;
  • 第三,APISIX 是一個開源項目,介紹咱們在只有兩我的的狀況下是怎麼去作測試和持續集成,裏面會涉及 OpenResty 的一些通用的東西,值得你們借鑑。

API 網關的做用

什麼是 API 網關

以 Kong 爲例,左圖沒有 API 網關,可是後面掛了不少服務,若是每一個服務都要實現包括認證、統計、安全校驗等功能,會有不少重複的工做。API 網關的做用就是把這些公共的東西抽取出來,如右圖,下面的這幾個服務,每一個服務都只關心自身業務相關的東西,和業務無關的東西所有都丟到API 網關上,即 API 網關就是把公共的東西如統計、安全、限流、限速、緩存等提取出來作了一箇中間層。json

API 網關的傳統功能

  • 讓 API 請求更安全、更高效的獲得處理。傳統的 API 網關有一些基本的功能直到如今都適用的,管理無論南北向的仍是東西向的 API 流量能夠可以快速、安全地獲得處理,這個是 API 網關最原始的目的。
  • 覆蓋 Nginx 的全部功能。API 的網關覆蓋了 Nginx 的全部功能,包括反向代理、負載均衡以及基本的緩存、安全的認證、限流限速等。
  • 支持 Nginx 等 Web 服務器實現不了的功能。如動態上游、動態 SSL 證書、動態限流限速,以及主動/被動健康檢查、服務熔斷等,這些動態的能力都是傳統的 Nginx、Apache 這類Web 服務器支持不了的。
  • 全生命週期管理。在 API 網關領域,最大的玩家是谷歌,谷歌在 2016 年收購了一家上市公司 Apigee,它如今把整個功能集成在谷歌雲上。API 網關除了咱們熟悉的反向代理、負載均衡、限流限速的插件外,它還包括了 API 的設計、文檔以及測試等,這一整套都屬於 API 網關的功能,咱們叫作 API 的全生命週期管理,從項目設計到測試上線,全部的東西都在整個 API 網關的功能範疇內。

雲原生下的新功能

爲何如今包括 Kong、APISIX 還要把傳統的東西再作一遍呢?這是由於在雲原生和微服務體系下,用戶和技術架構有了一些新的變化:ubuntu

技術架構新變化

  • 須要對接雲原生裏面像 Prometheus、Zipkin、Skywalking 等重要組件;
  • gRPC 代理和協議轉換(REST<=>gRPC):HTTP 這種協議在微服務裏面用的愈來愈少,不少人開始用 gRPC,那在從 HTTP 到 gRPC 協議的轉換,這種功能也是須要的,包括 gRPC 的代理;
  • 身份認證方式改變:在傳統的 Nginx 裏面,通常是流量進來後根據路由的規則去作反向代理、負載均衡,不多對發流量的客戶端的身份作認證。可是在雲原生裏面就不同,由於不少是在微服務裏的流量,這裏面須要作嚴格的身份認證,包括加密、OpenID 之類的身份認證。這塊就是一些新的功能,能夠把本身企業裏面須要作身份認證相關的東西放到第三方的外部認證的廠商去作;
  • Serverless 也是最近幾年很是火的一個概念,好比但願在邊緣節點上面動態地把一個函數跑起來或者把一個函數給停掉,或者動態地去改裏面的內容,你能夠把你的 API 網關部署在邊緣節點上,具有了這種 FaaS 的功能,你的邊緣節點就會更加地靈活。APISIX 裏面最近就支持了 Serverless,可讓你的一個 Lua 的函數動態地在邊緣結點跑起來;
  • 無狀態、隨意擴容和縮容:API 網關在十多年前性能要求沒有那麼高,由於當時互聯網的流量更多地是從瀏覽器到服務端,沒有手機和物聯網的設備,也沒有微服務、內網這些流量。可是如今的流量很大,包括 4G、5G下面有不少的手機、IoT 設備去訪問服務端,流量特別地大。此時,就須要一個性能更高的 API 網關去作支撐。雲原生的一個重要的標準是全部的服務均可以經過容器的方式隨意地去擴容和縮容,對 Kubernetes 友好;
  • 支持多雲和混合雲:如今上雲已是一個趨勢,可是咱們通常不太會把服務只放在一個雲上,好比騰訊雲、谷歌雲、阿里雲各放一部分,私有云再放一部分,根據它們的安全和價格作調整,私有的一些數據安全性更高的放在私有云上,資源好比和 CDN 相關的哪一個便宜就放哪一個雲上,作動態的切換,那麼此時就須要有一個和廠商無關的 API 網關放在前面作分發。

應用

舉兩個例子,介紹下新的 API 網關是作什麼的。api

  • 替換 Nginx 的全部功能處理南北向的流量

它和 Nginx 比好處很明顯,是徹底動態來實現的,無論是 Kong 或 APISIX,動態的都是最基本的點。在 Nginx 裏面修改任何一個配置文件,都須要 reload 以後才能生效的。咱們設想一個場景,用 Nginx 作最前面的路由,作負載均衡,突發的流量來了,此時須要快速地增長不少上游服務器,就要不停地修改 Nginx 配置文件,而後 reload,等突發流量過了以後再把上游的服務摘掉,那麼這時候還要再改 Nginx 文件並 reload 。這個代價是很大的,可是你若是用 Kong、APISIX 這種 Web 服務器,就不會有這樣的問題,經過 API 能夠很輕鬆地實時修改整個集羣裏面全部機器上游的配置、動態證書的配置,固然性能會比 Nginx 稍微低一點,可是這個低也是能夠接受的,由於它帶來了很大的靈活性。如今不少的廠商都是在作這樣的替換,不只互聯網公司,還有一些傳統企業都在把 Nginx 慢慢地拿掉。瀏覽器

  • 零信任網關

近兩年安全領域裏很火的概念就是零信任,即zero trust。在傳統的安全領域裏面,咱們認爲邊界防禦很是重要,因此會用防火牆對進來的流量作一層校驗,這個校驗實際上是命中規則的校驗,若是是黑的就把它拒絕掉。那麼這個時候就會有一個問題:若是一些規則更新不及時,它就能夠穿越防火牆,之前的安全更可能是基於邊界的防禦,過了邊界內網是能夠暢通無阻的。緩存

可是零信任網關能夠完全解決這個問題,它認爲全部的流量都是不安全的,之前的邊界防禦是非黑即白。如今的零信任安全網關則是非白即黑,你不是白的,那麼你就是黑的,因此它是徹底基於身份來認證的。一個 API 的請求過來會到身份認證的服務器,第三方的身份認證廠商好比 Author0、OKTA 的身份認證服務器認證你的身份,身份認證過了,請求才能夠經過,否則就直接拒絕掉,這是是安全領域的一個趨勢。

企業用戶的需求

  • 不鎖定,可回退

全部企業用戶的最大需求都是:不要鎖定用戶。API 網關是整個流量的入口,不能把用戶鎖定在裏面。好比你用了阿里雲的 API 網關,其實你就已經被它鎖定了,由於它是流量的入口,你沒有辦法分發到其它雲廠商上。此外還須要可回退,我使用了這個API 網關,好比原來是 Nginx,我能夠很輕鬆地回退過去,這也是咱們在作 APISIX 會考慮到的。可能用戶以爲用了一段時間不爽,想退回 Nginx,咱們也能夠支持這種能力。

  • 保持核心的穩定

APISIX 雖然每月的迭代很是快,每月有 200 多個 commit,有 10 個左右大的功能,可是 APISIX 裏面有一個叫 core 的目錄變化是不多的,咱們會保持它的核心是穩定的。功能迭代能夠很快,可是核心很穩定。

  • 支持企業個性需求的開發

不管是國內仍是國外的企業,都沒有辦法拿產品去適應全部的需求。若是你適應了全部的需求,那麼你就作成了一個巨無霸,會是個很大很雜的產品,它的性能、可擴展性就會降的很低。因此咱們就有插件,若是你須要有個性化的東西,就去定製本身的插件,須要什麼功能就把這個插件放上去,不須要就把它拿掉。我能夠保證最下面核心層是很穩定的,上面那層能夠根據用戶需求定製。

如何作網關的選型

行業現狀瞭解

  • 參考 Gartner 報告

這個是咱們選型的思路,咱們作選型並非先從技術上去作,而是先看整個行業,Gartner 的報告能夠做爲參考。如上圖所示,谷歌、IBM、RedHat 等頭部玩家吃掉全球大部分 API 市場,雖然技術圈都知道 Kong,但它其實處於遠見者的地位,此外Kong 做爲新興的玩家仍是第一個將自身 API 網關開源出來的。

  • 參考 CNCF 全景圖

Gartner 的報告更偏商業化,能夠在此基礎之上參考開源社區中雲原生軟件基金會CNCF 維護的全景圖,不少開源和閉源項目都被其分層、分功能地羅列出來。全景圖中雲原生領域有十幾款軟件是作 API 網關選型時能夠選擇的,其中有一半是大廠的產品,如 3SCALE 是Red Hat 的產品,剩下的 Kong、APISIX、TYK 等是開源項目,若是要作 API 選型能夠在其中作選擇。

產品選型比較

在參考 Gartner 報告和 CNCF 全景圖以後,咱們比較了主流的 API 網關,決定不用已有的 API 網關而是要本身作一個。

  • apigee

apigee 是最大的玩家,其優點在於全生命週期,即從 API 設計、開發、文檔、測試以及上線等所有是谷歌全家桶。但 apigee 是閉源項目,沒法進行定製化開發,並且是被谷歌雲鎖定的。

  • Kong

Kong 解決了 apigee 的痛點,既不會鎖定也支持自定義開發,但 Kong 是 2015 年開發的,當時是把數據都放在Postgres 比較重的關係性數據庫裏,代碼繁雜,性能存在問題。Kong 的優點在於產品思路好,方向看得準。

  • APISIX

APISIX 借鑑 Kong 的思路,選型時徹底基於 etcd,將全部的數據都放在 etcd 裏面,完成 Kong 在postgres 上作的大量重複代碼,例如消息分發、高可用和可擴展性都是基於 etcd 進行,操做更加簡單。APISIX 的不足在於開源時間短,從 2019 年 6 月 6 號開源到如今還沒有經受大用戶的檢驗,但優點明顯:二次開發難度比 Kong 小不少。以限流限速功能開發舉例, 在 APISIX 的文件裏增長六七十行代碼就能完成,但 Kong 則須要修改五六個文件、兩三百行代碼。

如何作網關的技術選型?

API 網關的核心組件:

  • 路由,路由能夠認爲是 Nginx 裏面的各個 location,怎麼把 location 分發到上游服務將各個插件加載起來是路由的一個功能。選擇時須要思考的是作遍歷仍是作一個樹?兩者須要的時間和複雜程度是不同的,咱們選擇像 Kong 同樣作遍歷。
  • 插件,插件是 API 網關的核心功能,有了插件就能夠很輕鬆地開發屬於本身的代碼,而不用等開源社區增長相關功能。在作插件時須要思考要不要作成熱加載,熱加載的意義在於新增插件或者修改某一個插件時,不須要重啓整個服務就能生效。咱們但願作到修改或新增插件時,能夠經過 API 的調用立刻生效。
  • schema 的校驗,schema 的校驗指的是用戶請求進來後須要校驗上傳的字段、類型等是否合法,若是本身寫插件,其參數、輸入值是否合法,這至關因而對 API 的描述,使得我的和前端的配合十分便利。
  • 存儲, 放在關係型數據庫仍是鍵值數據庫,亦或是放在 etcd 裏等同因而在作技術選型,須要把這些都選好後才能像搭積木同樣搭建起來。

選型原則:作雲原生友好的、高性能的、開源的 API 網關

  • 要對開發者友好。使用 API 網關的是開發者,咱們但願無論是開發者看代碼、學代碼仍是修改插件都能很輕鬆,不用像我和院生當時看 Kong 的代碼那樣痛苦。
  • 追求性能。雖然說 OpenResty 的性能高,可是真正動手寫的時候會發現寫出來的代碼性能不高,由於在 OpenResty 裏面代碼都是很容易寫,可是很難保證寫出一個極致的代碼,它裏面有很是多的坑,這是大部分人很難去注意到的。

APISIX 的選型

  • 路由:最開始選擇 lua-resty-r3,最近新增路由 FFI;
  • 插件:靈感來自 Kong,但架構和設計徹底不同,大幅簡化編寫難度,熱加載;
  • schema:借用騰訊開源的 rapidjson,在 rapidjson 實現 json schema,用 json schema標準作校驗;
  • 存儲:選用 etcd,當時沒有 Lua-resty-etcd 庫,須要從頭 lua 幫助 etcd 進行訪問。

APISIX 獨有的功能

  • 超強性能,性能是主打標籤,內部測試發現 APISIX 的性能是 Kong 的 10 倍;
  • 插件熱更新,修改或增長插件,不用重啓服務,全部的更新都是熱的;
  • 路由能夠實現插件化,若是不喜歡 r3 的複雜路由,可使用前綴匹配的路由;
  • 支持版本變動控制,若是發佈新版本出錯能夠輕鬆回退老版本;
  • 以身份爲基礎的零信任,新合併的 future 能夠支持外部身份認證,此時很容易實現零信任,能夠接入全部外部身份認證廠商的服務。使用時只需簡單調配部分參數,就能夠將身份認證功能直接加入 API 中。Kong 的商業版也支持此功能,但 APISIX 直接開源。

測試、持續集成的最佳實踐

測試

大公司都有專門的 QA 團隊作測試,開發部門只須要寫完代碼簡單自測後提交給 QA 團隊。但開源項目沒有 QA 團隊,甚至連開發團隊都是兼職,此時就必須用自動化的測試,即測試驅動開發的方式才能玩轉開源項目。

OpenResty 的開源項目將近 70 個,其商業公司有將近 100 個閉源的項目,總共將近 200 個項目不到 10 我的維護。若是手工測試,那就什麼都作不了,因此要想辦法實現解決這個問題。

  • 開發即測試

剛開始較慢,由於開發完一個新功能須要一塊提交對應的測試案例,不然PR 不會被合併。例如給 OpenResty 貢獻一個功能卻沒有提交對應的測試案例,或者提交了測試案例但不全,無論功能寫的有多好,此PR 必定不會被合併,由於破壞了整個開源項目的原則,測試須要是自動化跑起來的。

APISIX 多引入一個條件,即代碼的覆蓋率不能低於70%,如今已經改成不能低於 80%。若是你的改動引入新代碼,也增長了測試案例,可是下降了原有測試案例的覆蓋率,那也不能被接受合併。

  • 單元測試徹底基於 test:nginx

測試案例徹底基於 test:nginx ,能夠認爲 test:Nginx 是一個小語言或者一個DSL,文檔較少,學習門檻比較高,我和院生對它比較熟悉才徹底基於此進行測試。

  • 代碼風格檢測:luackeck 和 lua-relang

Luackeck 很是好用,能夠用於 Lua 和 OpenResty,提供有幾個參數進行選擇,還可使用春哥寫的 lua-relang。咱們是兩個程序都跑起來作代碼風格檢測,以確保無論是新的提交者仍是咱們本身的代碼風格的一致性。

  • 代碼覆蓋率檢測:luacov

代碼覆蓋率檢測使用luacov,這是標準 lua 的一個功能,能夠將代碼覆蓋率跑起來。

合併 PR 是在上述測試即 test:nginx 測試、代碼風格測試、代碼覆蓋率測試都跑過的前提下進行,每個月 6 號發行新版本時進行性能測試,比較新老版本之間性能的差別。通常會跑火焰圖,同時按期作fuzzing 測試,混亂輸入如 uri、args 等作壓力測試。畢竟 APISIX 是一個 API 網關,做爲流量的入口要保證足夠的穩定。

持續集成

測試不能依賴於人,不然總有一天會跑不下去。那麼如何讓單元測試、性能測試、代碼風格檢測等測試不依賴於人穩定地運行呢?

  • 強依賴 GitHub:issue、Milestone、code review、PR approved。GitHub 的 code review 很是好用,它能夠評論每一行代碼,若是它以爲這行代碼必需要改動,而實際沒有修改,是沒有辦法合併 approved。
  • 強依賴 travis CI:單元測試、代碼風格檢測、多平臺測試(ubuntu 和 mac)、前端打包、自動提交。travis 是 GitHub 的持續集成插件,APISIX 並無用本身的服務器資源去跑測試,而是跑在雲端的,如今自帶APISIX 的前端,其打包、提交都是自動化進行。由於咱們要從vue 的代碼編譯爲 html,這一切都是經過 travis 來作的。
  • http://coveralls.io,將代碼覆蓋率的結果上傳到http://coveralls.io 網站,以可視化的方式呈現全部和代碼覆蓋率相關的東西,例如哪一行代碼沒有被檢測到,和上一個版本有什麼變化等,使得代碼覆蓋率檢測自動化進行。前文曾提到要始終保證 APISIX 的核心穩定,這就須要保證core 目錄裏全部文件代碼覆蓋率可以達到 100%,即核心板塊的每一行代碼都被測試到。

總結

  • 資源少不必定是壞事。無論是開源項目仍是商業公司,只有在資源少的時候,纔會思考如何藉助外部的力量或者是想出一些鬼點子解決問題;
  • APISIX 的選型、測試和 CI 都是找「取巧」和自動化的方式,藉助巧用外部力量的方式去作,沒有造輪子;
  • APISIX 的選型、測試和 CI 三者很是重要,比性能重要。雖然咱們主打性能,但更值得你們琢磨的不僅是代碼,而是選型怎麼測試和 CI 的,你們能夠將其運用到業務中,即便不用 OpenResty 和 APISIX,仍是能夠學習開源項目是怎麼作的;
  • GitHub 和 SaaS 能提供的服務,絕對不會本身去造,剋制住本身造輪子的衝動。

查看演講PPT及視頻:

API 網關的選型 測試和持續集成

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索