滿足基本要求的業(yè)務網(wǎng)關(guān)
Spring Cloud Gateway 是 Spring Cloud 生態(tài)系統(tǒng)中的一個 API 網(wǎng)關(guān)逾冬,基于 Spring Boot 和 Spring WebFlux 框架構(gòu)建,提供了一個基于路由的毙沾、非阻塞式的 API 網(wǎng)關(guān)解決方案仇哆。
下面是 Spring Cloud Gateway 網(wǎng)關(guān)的優(yōu)劣勢分析:
優(yōu)勢
- 非阻塞式異步編程模型:Spring Cloud Gateway 是基于 Spring WebFlux 框架構(gòu)建的迫肖,使用了 Reactive Stream 的異步編程模型柏腻,能夠提供更高的并發(fā)能力和更低的延遲冯挎。
- 基于路由的請求處理:Spring Cloud Gateway 的核心功能是基于路由的請求處理,能夠?qū)⒉煌恼埱舐酚傻讲煌暮蠖朔丈厦Ф冢⑻峁┴S富的路由配置選項。
- 高度可擴展:Spring Cloud Gateway 提供了豐富的擴展點和插件機制切距,可以自定義路由朽缎、請求轉(zhuǎn)發(fā)、限流等功能谜悟。
- 集成 Spring Cloud 生態(tài)系統(tǒng):Spring Cloud Gateway 能夠無縫集成 Spring Cloud 的各種組件话肖,如 Eureka、Ribbon葡幸、Hystrix最筒、Zipkin 等,提供全面的服務治理和監(jiān)控能力蔚叨。
劣勢
- 學習成本高:Spring Cloud Gateway 采用了基于函數(shù)式編程的 Reactive Stream 異步編程模型床蜘,需要對相關(guān)概念、框架和 API 有一定的理解和掌握才能使用和定制蔑水。
- 性能瓶頸:Spring Cloud Gateway 的性能瓶頸主要集中在 CPU 和內(nèi)存上邢锯,處理高并發(fā)請求時需要保證機器資源充足。
- 無法完全替代傳統(tǒng) API 網(wǎng)關(guān):Spring Cloud Gateway 雖然提供了基于路由的請求處理能力搀别,但無法完全替代傳統(tǒng)的 API 網(wǎng)關(guān)丹擎,如 Nginx 和 Kong 等,因為一些傳統(tǒng) API 網(wǎng)關(guān)的功能,如高級的負載均衡蒂培、緩存和安全性等再愈,還未完全支持。
綜上所述护戳,Spring Cloud Gateway 是一款強大的 API 網(wǎng)關(guān)解決方案翎冲,能夠提供高并發(fā)、低延遲灸异、可擴展府适、易集成的優(yōu)勢,但需要承擔一定的學習成本肺樟,并面臨一些性能和功能上的限制檐春。
業(yè)務量達到一定量級后性能不足
上面已經(jīng)提到,Spring Cloud Gateway 無法替代傳統(tǒng)網(wǎng)關(guān),其原因也是因為是JVM。
JVM優(yōu)劣勢
優(yōu)勢
跨平臺性
JVM 提供了一種統(tǒng)一的么伯、跨平臺的執(zhí)行環(huán)境疟暖,使得基于 JVM 的編程語言具有跨平臺性。只要有支持 JVM 的平臺田柔,就可以運行基于 JVM 的應用程序俐巴,不需要針對不同的平臺進行編譯和部署。
垃圾回收
JVM 提供了自動的垃圾回收機制硬爆,可以自動管理內(nèi)存欣舵,避免了程序員手動管理內(nèi)存所帶來的諸多問題,如內(nèi)存泄漏和野指針等缀磕。
高效的即時編譯
JVM 采用即時編譯技術(shù)缘圈,可以將 Java 代碼在運行時動態(tài)編譯成本地機器碼,從而提高了程序的執(zhí)行效率袜蚕。
劣勢
啟動時間較長
基于 JVM 的應用程序啟動時間相比于一些其他的編程語言糟把,如 Go、Node.js 等牲剃,要長一些遣疯,因為需要先啟動 JVM,再加載應用程序和類庫凿傅。
內(nèi)存占用較大
JVM 的內(nèi)存占用較大缠犀,因為 JVM 需要加載和管理大量的類和對象,并且需要維護一些額外的信息狭归,如堆棧和異常信息等夭坪。
并發(fā)性能問題
在高并發(fā)場景下,JVM 存在一些并發(fā)性能問題过椎,如鎖競爭室梅、線程上下文切換等。雖然 Java 語言提供了一些并發(fā)編程技術(shù),如鎖亡鼠、原子操作等赏殃,但使用不當容易引發(fā)性能問題。
由于需要較多的內(nèi)存以及啟動時間較長等問題,被很多程序員所吐槽间涵。換句話說同等級的應用仁热,JVM可能需要更多的資源。但是我相信 Java 會越來越強大,會將這些劣勢慢慢優(yōu)化掉勾哩。
Spring Cloud Gateway 路由原理
之所以上面簡單說了一下JVM的優(yōu)劣勢,是因為JAVA做網(wǎng)關(guān)或者中間件抗蠢,確實需要高的CPU和內(nèi)存資源。下面我簡單減少一下Spring Cloud Gateway路由的原理思劳,相信等我介紹完之后迅矛,大家就會發(fā)現(xiàn)其路由的性能瓶頸在哪了。
讓我們打開編譯器潜叛,找到RoutePredicateHandlerMapping#getHandlerInternal
這個方法的源碼秽褒。我已經(jīng)將源碼摘出來了。
從上面查找路由的方法中,我們就可以發(fā)現(xiàn)其性能瓶頸在逐條遍歷上威兜,如果當前有幾千個API销斟,可能看不出性能差距,當有上萬條API時椒舵,該方法的性能可能會大幅度降低蚂踊。拋去遍歷的時間復雜度 O(n) ,同時還要去每個路由內(nèi)去做條件過濾,才能找到符合條件的路由返回笔宿,進行下一步操作悴势。這樣即使我們有更高的內(nèi)存以及性能更好的CPU也沒辦法發(fā)揮出其硬件的實力。因為從根本上措伐,Spring Cloud Gateway的路由策略就限制了瓶頸。
Spring Cloud Gateway 路由優(yōu)化思路
我們知道了其性能瓶頸所在,下一步就是如何去優(yōu)化军俊。 由于之前研究了很多的網(wǎng)關(guān)侥加,比如Kong,Zuul,APISIX, 發(fā)現(xiàn)APISIX所使用的的路由算法非常的高效且穩(wěn)定。他所使用的的算法就是我上一篇提到的基數(shù)樹粪躬。如果感興趣可以去復習一下担败。我們也可以模仿APISIX,將Path的路由提取出來以基數(shù)樹的數(shù)據(jù)結(jié)構(gòu)保存,保存其他前置路由過濾方法镰官。大致的流程圖如下:
這樣我們不僅可以更搞笑的利用內(nèi)存(基數(shù)樹需要更多的內(nèi)存去存儲節(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
小結(jié)
由此可見,當使用基數(shù)樹做URL Path的路由查找的數(shù)據(jù)結(jié)構(gòu)的時候士鸥,成倍的提高了Spring Cloud Gateway 的吞吐量。并且我們通過Jconsole 觀察其運行狀態(tài)后烤礁,后者更無論是垃圾回收和CPU的使用率都是更優(yōu)讼积。 后續(xù)我會詳細講解優(yōu)化細節(jié)脚仔。