2019 年 10 月 27 日,又拍雲聯合 Apache APISIX 社區舉辦 API 網關與高性能服務最佳實踐丨Open Talk 杭州站活動,Apache APISIX PPMC 成員王院生作了題爲《 Apache APISIX 微服務網關極致性能架構解析》的分享。本次活動,邀請了來自阿里巴巴、螞蟻金服、Apache APISIX、PolarisTech、又拍雲等企業的技術專家,分享網關和高性能服務的實戰經驗。html
王院生,深圳支流科技創始人,Apache APISIX PPMC 成員,OpenResty 社區發起人,《 OpenResty 最佳實踐》做者。nginx
如下是分享全文:git
前言github
你們好,我是來自深圳支流科技的王院生。今年 3 月份,我和志同道合的夥伴一塊兒創業,發起了 APISIX 項目,目前這個項目已進入 Apache 孵化器。Apache APISIX 是一個高性能、可擴展的微服務 API 網關。它是基於 Nginx 和 etcd 來實現,和傳統 API 網關相比,APISIX 具有動態路由、插件熱加載、gRPC 協議轉換等功能,特別適合微服務體系下的 API 管理。golang
Apache APISIX 是一個蓬勃發展的開源項目,在 2019 年 6 月 6 號開源後,很快就得到了開發者的關注和興趣,並在開源一個月後被收錄到 CNCF(雲原生軟件基金會) 的全景圖中。如今 Apache APISIX 在 GitHub 有 1500 多個 star,近40 多名貢獻者,是一個彙集了 800 多人的開發者社區。從開源之初,APISIX 保持每月發佈一個版本,並堅持測試驅動開發、自動化 CI/CD 等理念,以保證代碼的質量和穩定性。web
API 網關並不是一個新興的概念,在十幾年前就已經存在了,它的做用主要是做爲流量的入口,統一處理和業務相關的請求,讓 API 更加安全、快速和準確的獲得處理,它有如下傳統功能:數據庫
最近幾年,業務相關的流量再也不僅僅是由 PC 客戶端和瀏覽器發起,更多的來自手機、IoT 設備等,將來隨着 5G 的普及,這些流量會愈來愈多。同時,隨着微服務架構的結構變遷,服務之間的流量也開始爆發性的增加。在這種新的業務場景下,對 API 網關有了更多新需求:json
有了這些功能,微服務只需關心業務自己,而與業務相關的周邊管理功能,好比服務發現、服務熔斷、身份認證、限流限速、統計、性能分析等,都可以在獨立的網關層面解決。從這個角度來看,API 網關既能夠替代 Nginx 的全部功能處理南北向的流量,也能夠勝任 Istio 控制面和 Envoy 數據面的角色,處理東西向的流量。api
目前已經有不少可選的網關產品,爲何咱們還要進入這個行業進行摸索?咱們對現有的產品進行了分析:瀏覽器
行業老大們的技術方案大多基於 Java + JS 無一例外,由於他們都是十幾年前起步,倒退到那個年代能選的方案也只有 Java 。若是阿里是如今才起步的,我相信他也會有不一樣的技術選擇,可是在那個年代作大應用,只有 Java 可選。若是要作動態,基本也就只有 JS 這條路,最後的組合均爲 JAVA + JS 技術方案。它的問題也比較明顯:性能差,體態臃腫,二次開發較困難。
在 Ganter 中遠見者行列採用的技術方案目前可能是基於 OpenResty 和 Golang,可以看到這些行業遠見者在具體實現上,總體都比較重。代碼量重每每表明結構複雜,最後也發現他們確實效率不高。
在起步之初,咱們意識到必需要比遠見者還要好十倍以上,咱們纔有成功的可能。此時咱們看清了要走的一條路:第一要輕巧,第二須要性能極致。最後若是再有豐富的插件生態,就更完美了。
4 月初,咱們開始第一行代碼,咱們選擇在 6 月 6 日開源,由於產品名叫 APISIX,咱們但願它容易被你們記住。
7 月,APISIX 進入 CNCF 全景圖,這是目前最火的軟件基金會。
8 月,咱們擁有了第一家商業用戶,搞定商業用戶的過程確實很是爽,藉助 APISIX 內核前兩週,就幫用戶把 QPS 提高了一倍。
9 月,開源用戶貝殼找房正式上線,如今天天至少有 1 億的流量須要處理(截止目前已經有 2.5 億日流量),它的 CPU 大約 1% 左右。
9 月咱們也開始和 Apache 接觸,着手準備捐贈,10 月就真正成功了。這應該是國內第一家由初創公司捐贈的 Apache 項目。一般一個項目要進入 Apache 基本都是以年爲單位,但咱們只用了一個月。
10 月,咱們在繼續奔跑,已實現了全平臺支持。除了常見的操做系統,兩大主流 X86 架構和 ARM64 架構也均所有支持,並通過完整用例迴歸。APISIX 是一個測試驅動的項目,測試覆蓋率到 80% 以上,只要測試用例能完整運行,能夠確保在生產中正常使用。
如下是 Apache APISIX 引覺得傲的點,它們大可能是是競品徹底沒有的:
如上圖所示,圖 ① 爲網關最初的產品形態,左側是客戶端,右側是服務,網關在他們中間;因爲服務會作彙集分類,如圖 ② 中服務分紅兩類,此時 API 網關的重要性就體現出來,它須要對外作無感知,須要根據用戶請求的流量信息作分發,此時 API 網關就會成爲單點故障;由此演化出圖 ③ 的形態,有兩個 API 網關,它們均可以訪問後面的任何一個服務集羣,互爲備份,是一個高可用的基本形態,客戶端能夠請求任意一個網關;在圖 ④ 中,API Gateway 負責流量轉發,etcd 負責配置存儲,API Gateway 是管理人員的控制檯,因此若是隻有 API Gateway 高可用是遠遠不夠的。
真正可以讓用戶安心的方案應該是 API Gateway、配置中心、控制中心都可以完整支持高可用,做爲一個微服務 API 網關須要部署靈活,API Gateway、etcd、管理控制檯均須要知足任意數量伸縮,須要多少就部署多少。
這對咱們的開源版本提出了一個很是高的挑戰,安裝形態到底應該什麼樣子?
咱們須要有上圖中的三種形態都容許用戶去部署:Admin、Gateway、Gateway+Admin。咱們的解決方案首先是 All In One,即只有一個 「Gateway+Admin」 的包,當用戶須要將 Gateway 和 Admin 分別部署時,只需修改配置,是否啓用 Admin 就能夠實現。
咱們經過配置的方式簡單區分節點類型,而任何一個節點裏面,既能夠單獨包含一部分,如 Admin 或者 Gateway,也能夠同時包含兩者,這種方式讓用戶可以很容易地解決一堆問題,實現高可用、彈性伸縮、分佈式、集羣以及故障自動轉移。
下面介紹 API 網關的基本架構,這裏簡單對它作了拆分:
整個流程是管理員經過 admin API 告訴網關須要作什麼並保存下來,這也就是咱們常說的控制面。相對的是數據面部分處理外部用戶真實請求,要根據管理員的規則,對當前請求根據路由匹配獲得配置,而後執行配置中的插件並轉發到指定上游。
這裏涉及三個最基本問題:
若是這三個基本問題回答好,那麼這個網關質量也就基本肯定了。
核心思路:技術選型時須要思考到底須要解決什麼問題?
APISIX 配置中心並無選擇傳統的關係型數據庫,而是選用了 etcd,當時主要考慮到如下要素:
經過分析發現 etcd 很是適合咱們,當真正看到官方的 why etcd 的說明列表時(以下圖),咱們就知道咱們選對了。
語言和開發平臺:OpenResty
新選型 API 網關開發平臺基本只有兩條路,一個是Lua,即 OpenResty,另外一個就是 Golang。Golang 是靜態語言,其動態能力不如 Lua ,因此最後選擇 OpenResty。我我的從 2014 年到如今一直沉浸在 OpenResty 社區,對它的理解和把控力也會更好。
咱們是全新的項目,因此咱們直接基於最新的版原本作,OpenResty >= 1.15.8,Tengine>= 2.3.2,兩者都是基於 Nginx,搭配他們任何一個做爲運行時均可以運行 APISIX。
咱們須要藉助更通用的語言來吸納它的周邊生態,這方面 Lua 與 C/C++ 是不在一個量級,常見作法能夠經過調用 C/C++ 的動態庫來這麼作。此外,也能夠調用基於 Golang 的庫。從這個角度看,咱們選擇 OpenResty 做爲基礎平臺開展 APISIX 業務開發會很順暢,不用擔憂周邊庫匱乏的問題。並且 OpenResty 這幾年被用在 API 網關比較多,有不少現成組件也能夠利用,APISIX 可能只須要拿過來作二次整合。固然整合過程當中也發現了一些項目的開源版本寫得很差,二次優化的事情也沒少幹。
jsonschema 的數據校驗規範 Google 排名第一,換而言之,若是有校驗規範且已經排名第一,咱們沒有必要本身造一個,知識必定要能夠複用,因而選擇了 jsonschema 這個標準。這個校驗標準幾乎涵蓋了 C、Java、JS 等主流語言,並且官方提供現成的壓測結果。咱們任何選型都會格外關注性能表現,若是有現成的壓測框架和結果就很是棒。
固然,在實際操做中經歷了一些波折:最開始選型在 jsonschema 官方找實現,結果發現沒有適合咱們的,他們大多都是開源庫中用了一點便聲稱支持,實際上耦合度比較高。
咱們找到的第一個選型是 lua-rapidjson,它並不在 jsonschema 官方的推薦列表裏,是騰訊開源的。但 rapidjson 有一個比較大的問題是編譯條件高,它是一個 C/C++ 的實現,而咱們作的是開源的項目,簡單易用是咱們追求的。此外 rapidjson 只支持了 draft4 裏 95% 的內容,有些特性也不支持,好比常常用到的 default 。
因而咱們根據一個開源的方案進行改造,實現了新的 iresty / jsonschema,主要增長了下面一些點:
這個庫採用了編譯器的思惟方式。咱們對其進行了測試:一個簡單的對象裏面有兩個字段,分別是字符串和一個 int 類型,反覆進行循環壓力測試,跑一百萬次,將跑完的時間作比較。iresty / jsonschema 的性能是 lua-rapidjson 的 5-10倍,是 gojsonschema(golang) 性能的 500-1000 倍。
路由是 API 網關的生命,沒有高性能的路由,就沒有快速的匹配過程,API 網關的性能沒法提高。只有路由是 100% 每次參與用戶請求的,配置中心和參數校驗也不是,所以路由必需要高性能。同時路由匹配條件也要足夠靈活和強大,除了要支持最基本的 uri、host,其餘可選的如 IP 地址、請求參數、請求頭、Cookie 等也須要。
本來覺得作到這一步就能夠了,但開源項目的用戶仍是會有其餘的需求,最後我添加了自定義函數,用戶能夠寫 Lua 腳本,這也再次使用了 Lua 的動態特性。換而言之,用戶徹底能夠建立判斷規則,涉及特別很差表達或還未支持的邏輯,均可以用自定義函數方式先繞着走。
集大成者的路由 resty-radixtree,目前單核心每秒能夠達到百萬次的匹配,相比以前的選型 libr3,radixtree 的性能至少提高了一個數量級。而且它容許引用任意的 nginx 的內置變量,索引的自由建立也讓它輕鬆支持 uri 或 host+uri 的使用場景。
自此三個選型肯定:路由 resty-radixtree,校驗器 iresty / jsonschema,配置中心 etcd,Apache APISIX 雛形誕生。
如上圖,這是 Apache APISIX 目前的業務架構:左側是管理員,右側是用戶請求。管理員把信息錄入放到 etcd 裏面緩存後,用戶訪問 APISIX 作路由,根據路由信息獲得結果,匹配到路由交給具體的微服務、serverless 等。
如上圖,APISIX 軟件層面基本架構並無採用傳統的層層嵌套的方式,只有基礎層和業務層,基礎層徹底脫離於 APISIX 內核,徹底無業務綁定,你們能夠在任何 OpenResty 項目中引用。
插件能夠熱插拔,不用重啓服務。而且已經內置了常見的限流限速、身份認證、請求改寫、URI 重定向、opentracing、serverless 等插件,開箱即用。APISIX 對插件的支持和友商不太同樣,具體表如今如下幾點:
總結 Apache APISIX 三板斧以下:
Apache APISIX 目前已經具有 30 多個功能,已經基本超過大多開源競品。一般來講,引入了前面提到的幾十項功能,會伴隨着性能的降低,那麼究竟降低了多少呢?這裏我作了一個性能的測試對比。
如上圖,右側是我爲了測試寫的一個虛假的服務,這個服務是空的,只是把 ngx_lua 裏的一些變量拿出來,傳給了什麼都不作的 fake_fetch,後面的 http filter、log 階段等同樣,沒有任何計算量。
隨後對 APISIX 和右邊的虛假服務分別跑壓力測定,對比結果發現 APISIX 的性能僅僅降低了 15%,也就是說在接受了 15% 的性能降低的同時,就能夠享受前面提到的全部功能。咱們在阿里雲的計算平臺,單核下能夠跑到 23-24k QPS,4 核能夠跑到 68k 的 QPS。
歡迎你們經過 github 檢索 APISIX 瞭解更多,同時咱們也對外提供一對一的企業服務,歡迎感興趣的同窗和咱們聯繫。
以上就是王院生老師在 Open Talk 杭州站現場分享整理,舒適提示 12 月 14 日 API 網關與高性能服務最佳實踐·廣州站活動正在報名中 http://hdxu.cn/jB9KO
演講視頻觀看及 PPT 下載: