武林外傳—一燈大師與衆弟子漫談Api網關選型

南帝段王爺隱居桃源後,潛心研究,構築了一套武林祕籍訪問系統,系統是微服務部署的,拆分爲多個模塊,每個模塊只做一件事情。系統剛上線的時候非常順利,但隨着訪問量的增大,模塊的增多,新問題越來越顯現出來,他心中已有了七八成的主意,但想考一考身邊漁樵耕讀四大弟子,便將他們叫到自己跟前來,道:“自從我帶你們隱居桃源,你們整日遊山玩水,過得可是神仙般的日子,不知有沒有忘記技術的學習呀?”

漁樵耕讀四人齊聲道:“不敢忘記師父的教導!”

“好,你們思考下這個問題。當前,我們的服務越來越多,導致客戶端調用服務api時非常地麻煩,比如,有人要看一陽指祕籍,客戶端首先要訪問身份認證服務,然後是書籍查詢服務,然後是模擬演練系統,它需要知道怎麼去消費這三個不同的服務,而我們管理這些對外開放的接口也是一個問題。還有一個更要命的,最近歐陽鋒對九陰真經可謂虎視眈眈,我們的鑑權代碼散落在各個服務中,這樣的話工作量加大了,維護也非常不便,若是一個服務的鑑權代碼出了問題,歐陽鋒之輩便可以乘虛而入了。”

書生朱子柳是四弟子中最有學問的一個,他一聽便已明瞭,道:“師父,我們可以搭建一個網關係統,讓所有的外部請求都訪問這個Api網關,由網關來完成請求路由、權限驗證、負載均衡等功能。”

一燈大師捻鬚微笑道:“說得在理,不過籠統了些,Api網關,用什麼網關呢?”

樵夫道:“這選擇實在是多,有nginx,zuul,最近又推出了Spring cloud Gateway和zuul2。”

一燈大師道:“那你能說說他們之間的區別嗎?”

“這,這,嘿嘿......”樵夫摸摸腦袋笑着。

漁夫接過話來:“nginx以前主要是用作反向代理,如果要做一個完整的網關功能需要結合Lua進行擴展,Nginx 採用了異步非阻塞的方式來處理請求,可以同時處理成千上萬個請求的。一個 Worker 進程可以同時處理的請求數只受限於內存大小。目前市面上有基於nginx lua的框架,如Kong / Openresty,它藉助於Nginx的事件驅動模型和非阻塞IO,性能方面是非常棒的,下面是一個測試報告,在單核和雙核測試環境下,除直接訪問外,nginx的性能是最好的。”

命令模版:

ab -n 10000 -c 200 HTTP://<server-address>/<path to resource>

詳細測試報告: https://engineering.opsgenie.com/comparing-api-gateway-performances-nginx-vs-zuul-vs-spring-cloud-gateway-vs-linkerd-b2cc59c65369

“那zull呢,還有更新一些的Spring cloud Gateway和zuul2。zull是Netflix 開源的微服務網關組件,和spring cloud那一套結合得還是挺好的,我們的系統正是基於spring那一套搭建的,而且zull提供了許多的核心過濾器,通過這些過濾器,我們可以做許多的事,像動態路由、負載均衡、壓力測試等等,這些Nginx提供的並不全……全面。而且,我們也看到圖了,在較強的測試環境下(8 核),直接訪問、Nginx、Zuul 差距不大。” 農夫武三通說的太快,顯得有些結巴了。

朱子柳道:“你們難道對這個測試結果沒有任何懷疑嗎?我們的架構雖然用了spring boot的,但主要還是架構於Dubbo之上的,況且zull基於 Servlet 框架構建,採用的是阻塞和多線程方式,即一個線程處理一次連接請求,當出現問題時,如後端延遲或設備錯誤重試,活躍的連接和線程數量會增加,這會加大服務器負載並可能使集羣無法承受。較新的Spring cloud Gateway和zuul2倒是不錯,zull2基於Netty,是非阻塞的,支持長連接,但Spring Cloud暫時還沒有整合計劃,這個高性能版的Zuul 2在經過了多次跳票之後,Spring可能不願意再繼續等待,便自己研發了Spring Cloud Gateway,這纔是真正和spring cloud高度整合的,剛出來不久,有人對它的性能作過測試,從上面圖表看,性能並不理想,但測試結果並不準確,對此官方已經作了說明(https://github.com/spring-cloud/spring-cloud-gateway/issues/124) ,主要是說Spring Cloud Gateway依賴Reactor Netty,Reactor Netty不支持HTTP 1.0,用ab作壓測結果並不準確,使用wrk測試結果如下,Avg Req/Sec/Thread值是zuul的近1.6倍。”

Proxy

Avg Latency

Avg Req/Sec/Thread

gateway

6.61ms

3.24k

linkered

7.62ms

2.82k

zuul

12.56ms

2.09k

none

2.09ms

11.77k

“那你是支持用Spring cloud Gateway的嘍?”漁夫問道,他一向很重視這位讀書人的意見。

“網關的選型,沒有最好的,就看適合不適合現有系統的,目前,弟子幾個功力有限,不然完全可以基於Netty自主研發一個網關係統。目前從性能上講,這些技術都是足夠應付目前的訪問量的,從與現有系統的整合來看,我們內部服務是使用Dubbo和zookeeper實現服務間的註冊與發現的,當在Dubbo中使用基於HTTP的REST協議,後端服務才能被zuul直接調用,假如採用服務發現的形式調用服務,zuul可以通過Netflix/eureka實現服務發現,而Dubbo與eureka又不能很好地結合……”朱子柳陷入了沉思之中。

一燈大師見弟子說到了要緊處,道:“這點你考慮得非常好,不過,不用擔心,其實很久以前,大理王宮裏的系統就用過zuul,也遇到類似的問題,當時有位高人自己研發了一套內部接口,用於服務發現,只要對接這套接口,傳入應用名稱和環境,返回ip列表,就可以實現了。”

“關於整合方面,還待我深思,單考慮網關本身,我們該選擇什麼呢?”朱子柳問。

“剛纔你們都列舉了幾個方案,Kong,zuul,zull2,Spring Cloud Gateway。哪一種方案你們最有把握實現。”

“我們都是java一系的,對Kong的擴展不夠熟悉,而且對新出不久的技術不放心使用,從網上的性能測試爭議也可知新技術使用還未經歷足夠的實踐的考驗。既然大理段氏對zuul有過豐富的使用和擴展經驗,而且依據現有的每秒請求量,也足夠應付了,那就,那就用它吧?” 漁夫道。

一燈大師想:這些弟子,只想着用現成的成熟老技術,也不無不妥,目前系統急需改造,讓弟子們深入瞭解這些框架,仔細考證,也不是一時之間的事情,自己已經放手讓他們去幹了,不便干涉,但以後必須對他們進行全方位的培養。

“你們知道怎麼用zuul搭建一個網關嗎?關於zuul的使用,你們先看下這幅圖。請求的週期基本如此。主要是pre、route、post三種類型的過濾器。”

“嗯,這個實際配置也很簡單呀,如果使用spring boot的話,只要在應用主類加@EnableZuulProxy開啓zuul,再在application.properties中配置Zuul應用的基礎信息,如:應用名、服務端口,路由等,如果需要自定義過濾器,實現ZuulFilter接口即可,官網上都有。”漁夫道。

官網配置步驟: https://spring.io/guides/gs/routing-and-filtering/

“很好,不過這只是冰山一角,你知道,加上@EnableZuulProxy,代表添加了多少默認的過濾器嗎?”一燈大師道。

“這……” 漁夫和農夫面面相覷,又看看書生。

“這個我倒是曾有過些瞭解。” 書生朱子柳大筆一揮,在牆上畫了張表格。

類型

順序

過濾器

功能

pre

-3

ServletDetectionFilter

主要用來檢測當前請求是通過Spring的DispatcherServlet處理運行,還是通過ZuulServlet來處理運行的

pre

-2

Servlet30WrapperFilter

主要爲了將原始的HttpServletRequest包裝成Servlet30RequestWrapper對象

pre

-1

FormBodyWrapperFilter

將符合要求的請求體包裝成FormBodyRequestWrapper對象

pre

1

DebugFilter

標記調試標誌,根據配置參數zuul.debug.request和請求中的debug參數來決定是否執行過濾器中的操作

pre

5

PreDecorationFilter

處理請求上下文供後續使用

route

10

RibbonRoutingFilter

serviceId請求轉發

route

100

SimpleHostRoutingFilter

url請求轉發

route

500

SendForwardFilter

forward請求轉發

post

0

SendErrorFilter

處理有錯誤的請求響應

post

500

SendForwardFilter

處理forward

post

1000

SendResponseFilter

處理正常的請求響應

“嗯,很好,學習技術,不僅要知道怎麼用,還要儘可能多地知道它的原理,這樣有什麼問題也能很快找到思路去解決,不然,只能像無頭蒼蠅一樣,網上各種搜索,一個個去試,最後就算解決了問題,腦子裏還是一頭霧水,這不利於你們將來的發展。”

“謝師父教誨。”漁樵耕讀齊聲道。

“去吧,這個事就交給你們了,有問題相互之間要及時溝通。” 一燈大師揮了揮手,讓衆弟子出去忙了。最近,他師弟從天竺帶來微服務七篇,他要閉關細細研習一番,等參透了,和衆弟子講解。

java達人

ID:drjava

(長按或掃碼識別)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章