一、API網關
微服務架下,服務之間容易形成網狀的調用關系,這種網狀的調用關系不便管理和維護,這種場景下API網關應運而生。作為后端服務的入口,API網關在微服務架構中尤其重要,在對外部系統提供API入口的要求下,API網關應具備路由轉發、負載均衡、限流熔斷、權限控制、軌跡追蹤和實時監控等功能。
目前,很多微服務都基於的Spring Cloud生態構建。Spring Cloud生態為我們提供了兩種API網關產品,分別是Netflix開源的Zuul1和Spring自己開發的Spring Cloud Gateway(下邊簡稱為Gateway)。Spring Cloud以Finchley版本為分界線,Finchley版本發布之前使用Zuul1作為API網關,之后更推薦使用Gateway。
雖然Netflix已經在2018年5月開源了Zuul2,但是Spring Cloud已經推出了Gateway,並且在github上表示沒有集成Zuul2的計划。所以從Spring Cloud發展的趨勢來看,Gateway代替Zuul是必然的。
1.1 Zuul1簡介
Zuul1是Netflix在2013年開源的網關組件,大規模的應用在Netflix的生產環境中,經受了實踐考驗。它可以與Eureka、Ribbon、Hystrix等組件配合使用,實現路由轉發、負載均衡、熔斷等功能。Zuul1的核心是一系列過濾器,過濾器簡單易於擴展,已經有一些三方庫如spring-cloud-zuul-ratelimit
等提供了過濾器支持。
Zuul1基於Servlet構建,使用的是阻塞的IO,引入了線程池來處理請求。每個請求都需要獨立的線程來處理,從線程池中取出一個工作線程執行,下游微服務返回響應之前這個工作線程一直是阻塞的。
1.2 Spring Cloud Gateway簡介
Spring Cloud Gateway 是Spring Cloud的一個全新的API網關項目,目的是為了替換掉Zuul1。Gateway可以與Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等組件配合使用,實現路由轉發、負載均衡、熔斷等功能,並且Gateway還內置了限流過濾器,實現了限流的功能。
Gateway基於Spring 5、Spring boot 2和Reactor構建,使用Netty作為運行時環境,比較完美的支持異步非阻塞編程。Netty使用非阻塞的IO,線程處理模型建立在主從Reactors多線程模型上。其中Boss Group輪詢到新連接后與Client建立連接,生成NioSocketChannel,將channel綁定到Worker;Worker Group輪詢並處理Read、Write事件。
二、對比
2.0 產品對比
下邊以表格形式對Zuul1和Gateway作簡單對比:
對比項 | Zuul1.x | Gateway |
---|---|---|
實現 | 基於Servlet2.x構建,使用阻塞的API。 | 基於Spring 5、Project Reactor、Spring Boot 2,使用非阻塞式的API。 |
長連接 | 不支持 | 支持 |
不適用場景 | 后端服務響應慢或者高並發場景下,因為線程數量是固定(有限)的,線程容易被耗盡,導致新請求被拒絕。 | 中小流量的項目,使用Zuul1.x更合適。 |
限流 | 無 | 內置限流過濾器 |
上手難度 | 同步編程,上手簡單 | 門檻較高,上手難度中等 |
Spring Cloud集成 | 是 | 是 |
Sentinel集成 | 是 | 是 |
技術棧沉淀 | Zuul1開源近七年,經受考驗,穩定成熟。 | |
Github used by | 1007 repositories | 102 repositories |
Github issues | 88 Open / 2736 Closed | 135 Open / 850 Closed |
注:Github used by和Github issues統計時間截止2019/8/26。
2.1 性能對比
2.1.1 低並發場景
不同的tps,同樣的請求時間(50s),對兩種網關產品進行壓力測試,結果如下:
tps | 測試樣本Zuul1/Gateway,單位個 | 平均響應時間Zuul1/Gateway, 單位毫秒 | 99%響應時間小於Zuul1/Gateway,單位毫秒 | 錯誤比例Zuul1/Gateway |
---|---|---|---|---|
20tps | 20977 / 20580 | 11 / 14 | 16 / 40 | 0% / 0% |
50tps | 42685 / 50586 | 18 / 12 | 66 / 22 | 0% / 0% |
並發較低的場景下,兩種網關的表現差不多
2.1.2 高並發場景
配置同樣的線程數(2000),同樣的請求時間(5分鍾),后端服務在不同的響應時間(休眠時間),對兩種網關產品進行壓力測試,結果如下:
休眠時間 | 測試樣本Zuul1/Gateway,單位個 | 平均響應時間Zuul1/Gateway, 單位毫秒 | 99%響應時間小於Zuul1/Gateway,單位毫秒 | 錯誤次數Zuul1/Gateway,單位個 | 錯誤比例Zuul1/Gateway |
---|---|---|---|---|---|
休眠100ms | 294134 / 1059321 | 2026 / 546 | 6136 / 1774 | 104 / 0 | 0.04% / 0% |
休眠300ms | 101194 / 399909 | 5595 / 1489 | 15056 / 1690 | 1114 / 0 | 1.10% / 0% |
休眠600ms | 51732 / 201262 | 11768 / 2975 | 27217 / 3203 | 2476 / 0 | 4.79% / 0% |
休眠1000ms | 31896 / 120956 | 19359 / 4914 | 46259 / 5115 | 3598 / 0 | 11.28% / 0% |
Zuul網關的tomcat最大線程數為400,hystrix超時時間為100000。
Gateway在高並發和后端服務響應慢的場景下比Zuul1的表現要好。
2.1.3 官方性能對比
Spring Cloud Gateway的開發者提供了benchmark項目用來對比Gateway和Zuul1的性能,官方提供的性能對比結果如下:
網關 | Avg Req/sec/Thread | Avg Latency |
---|---|---|
Spring Cloud Gateway | 3.24k | 6.61ms |
Zuul1 | 2.09k | 12.56ms |
none | 11.77k | 2.09ms |
測試工具為wrk,測試時間30秒,線程數為10,連接數為200。
從官方的對比結果來看,Gateway的RPS是Zuul1的1.55倍,平均延遲是Zuul1的一半。
三、總結
Zuul1的開源時間很早,Netflix、Riot、攜程、拍拍貸等公司都已經在生產環境中使用,自身經受了實踐考驗,是生產級的API網關產品。
Gateway在2019年離開Spring Cloud孵化器,應用於生產的案例少,穩定性有待考證。
從性能方面比較,兩種產品在流量小的場景下性能表現差不多;並發高的場景下Gateway性能要好很多。從開發方面比較,Zuul1編程模型簡單,易於擴展;Gateway編程模型稍難,代碼閱讀難度要比Zuul高不少,擴展也稍復雜一些。