滿足基本要求的業(yè)務網關
Spring Cloud Gateway 是 Spring Cloud 生態(tài)系統(tǒng)中的一個 API 網關,基于 Spring Boot 和 Spring WebFlux 框架構建,提供了一個基于路由的、非阻塞式的 API 網關解決方案。
下面是 Spring Cloud Gateway 網關的優(yōu)劣勢分析:
優(yōu)勢
- 非阻塞式異步編程模型:Spring Cloud Gateway 是基于 Spring WebFlux 框架構建的,使用了 Reactive Stream 的異步編程模型,能夠提供更高的并發(fā)能力和更低的延遲。
- 基于路由的請求處理:Spring Cloud Gateway 的核心功能是基于路由的請求處理,能夠將不同的請求路由到不同的后端服務上,并提供豐富的路由配置選項。
- 高度可擴展:Spring Cloud Gateway 提供了豐富的擴展點和插件機制,可以自定義路由、請求轉發(fā)、限流等功能。
- 集成 Spring Cloud 生態(tài)系統(tǒng):Spring Cloud Gateway 能夠無縫集成 Spring Cloud 的各種組件,如 Eureka、Ribbon、Hystrix、Zipkin 等,提供全面的服務治理和監(jiān)控能力。
劣勢
- 學習成本高:Spring Cloud Gateway 采用了基于函數式編程的 Reactive Stream 異步編程模型,需要對相關概念、框架和 API 有一定的理解和掌握才能使用和定制。
- 性能瓶頸:Spring Cloud Gateway 的性能瓶頸主要集中在 CPU 和內存上,處理高并發(fā)請求時需要保證機器資源充足。
- 無法完全替代傳統(tǒng) API 網關:Spring Cloud Gateway 雖然提供了基于路由的請求處理能力,但無法完全替代傳統(tǒng)的 API 網關,如 Nginx 和 Kong 等,因為一些傳統(tǒng) API 網關的功能,如高級的負載均衡、緩存和安全性等,還未完全支持。
綜上所述,Spring Cloud Gateway 是一款強大的 API 網關解決方案,能夠提供高并發(fā)、低延遲、可擴展、易集成的優(yōu)勢,但需要承擔一定的學習成本,并面臨一些性能和功能上的限制。
業(yè)務量達到一定量級后性能不足
上面已經提到,Spring Cloud Gateway 無法替代傳統(tǒng)網關,其原因也是因為是JVM。
JVM優(yōu)劣勢
優(yōu)勢
跨平臺性
JVM 提供了一種統(tǒng)一的、跨平臺的執(zhí)行環(huán)境,使得基于 JVM 的編程語言具有跨平臺性。只要有支持 JVM 的平臺,就可以運行基于 JVM 的應用程序,不需要針對不同的平臺進行編譯和部署。
垃圾回收
JVM 提供了自動的垃圾回收機制,可以自動管理內存,避免了程序員手動管理內存所帶來的諸多問題,如內存泄漏和野指針等。
高效的即時編譯
JVM 采用即時編譯技術,可以將 Java 代碼在運行時動態(tài)編譯成本地機器碼,從而提高了程序的執(zhí)行效率。
劣勢
啟動時間較長
基于 JVM 的應用程序啟動時間相比于一些其他的編程語言,如 Go、Node.js 等,要長一些,因為需要先啟動 JVM,再加載應用程序和類庫。
內存占用較大
JVM 的內存占用較大,因為 JVM 需要加載和管理大量的類和對象,并且需要維護一些額外的信息,如堆棧和異常信息等。
并發(fā)性能問題
在高并發(fā)場景下,JVM 存在一些并發(fā)性能問題,如鎖競爭、線程上下文切換等。雖然 Java 語言提供了一些并發(fā)編程技術,如鎖、原子操作等,但使用不當容易引發(fā)性能問題。
由于需要較多的內存以及啟動時間較長等問題,被很多程序員所吐槽。換句話說同等級的應用,JVM可能需要更多的資源。但是我相信 Java 會越來越強大,會將這些劣勢慢慢優(yōu)化掉。
Spring Cloud Gateway 路由原理
之所以上面簡單說了一下JVM的優(yōu)劣勢,是因為JAVA做網關或者中間件,確實需要高的CPU和內存資源。下面我簡單減少一下Spring Cloud Gateway路由的原理,相信等我介紹完之后,大家就會發(fā)現其路由的性能瓶頸在哪了。
讓我們打開編譯器,找到RoutePredicateHandlerMapping#getHandlerInternal
這個方法的源碼。我已經將源碼摘出來了。
從上面查找路由的方法中,我們就可以發(fā)現其性能瓶頸在逐條遍歷上,如果當前有幾千個API,可能看不出性能差距,當有上萬條API時,該方法的性能可能會大幅度降低。拋去遍歷的時間復雜度 O(n) ,同時還要去每個路由內去做條件過濾,才能找到符合條件的路由返回,進行下一步操作。這樣即使我們有更高的內存以及性能更好的CPU也沒辦法發(fā)揮出其硬件的實力。因為從根本上,Spring Cloud Gateway的路由策略就限制了瓶頸。
Spring Cloud Gateway 路由優(yōu)化思路
我們知道了其性能瓶頸所在,下一步就是如何去優(yōu)化。 由于之前研究了很多的網關,比如Kong,Zuul,APISIX, 發(fā)現APISIX所使用的的路由算法非常的高效且穩(wěn)定。他所使用的的算法就是我上一篇提到的基數樹。如果感興趣可以去復習一下。我們也可以模仿APISIX,將Path的路由提取出來以基數樹的數據結構保存,保存其他前置路由過濾方法。大致的流程圖如下:
這樣我們不僅可以更搞笑的利用內存(基數樹需要更多的內存去存儲節(jié)點) ,并且提高了查詢的時間復雜度,由O(n)變?yōu)?O(m),其中m是鍵的長度。這樣查找的效率不會隨著API的增多更降低。從而提高路由效率。
優(yōu)化路由后性能對比
在這里我使用了Jmeter工具在本地電腦上進行了簡單的3分鐘壓測。 我本地電腦的配置是
CPU | RAM |
---|---|
i3-10100F( 3.6GHz) 4核8線程 | 64G |
直接壓測原應用
壓測原生Spring Cloud Gateway
壓測優(yōu)化后的Spring Cloud Gateway
小結
由此可見,當使用基數樹做URL Path的路由查找的數據結構的時候,成倍的提高了Spring Cloud Gateway 的吞吐量。并且我們通過Jconsole 觀察其運行狀態(tài)后,后者更無論是垃圾回收和CPU的使用率都是更優(yōu)。 后續(xù)我會詳細講解優(yōu)化細節(jié)。