最近花了一點時間系統的測試驗證了在SpringBoot框架下使用SpringMVC和Spring WebFlux兩種框架開發接口,對比了響應時間以及壓測吞吐量的區別。

WebFlux&SpringMVC
如果對WebFlux還不了解的同學,那么你需要學習了解一下。官網地址:https://spring.io/
實踐證明,使用WebFlux開發接口能夠大幅提升接口的吞吐量。
相關參數:
- 測試機器:Linux CentOS6.5 4核16G
- SpringBoot版本:2.2.2.RELEASE
- JDK版本:jdk1.8.0_151
本文主要內容如下:
- 使用tomcat容器的代碼演示
- 使用netty容器的代碼演示
- apachebench(ab)壓測接口,對比性能數據
文中代碼較多,建議大家收藏后,有時間自己親自動手開發並壓測來驗證結果。
tomcat容器下的代碼演示
我們先基於tomcat容器來驗證傳統的SpringMVC以及基於Project Reactor兩種方式開發接口的區別。
先來迅速搭建一個基於SpringBoot-2.2.2.RELEASE版本的demo項目,pom.xml核心依賴如下:

SpringBoot父級依賴

web依賴&project reactor依賴
項目啟動類:

再定義一個傳統的service,為模擬真實環境請求,service下的方法請求耗時100ms:

模擬耗時100ms
最后我們寫三個接口,每個接口采用不同的方式:
- 使用自定義調度器的方式
- 使用緩存的彈性調度器
- 傳統的SpringMVC方式
代碼如下圖所示:

三種接口開發方式
ab壓測
我們先對上面說的三個接口進行壓測,為避免網絡環境影響,我們直接在服務器上使用ab進行壓力測試。
壓測分三組,每組壓測這三個接口,每個接口發起10w請求,每組用戶數分別為200、500、1000,從而查看不同用戶數請求下的響應結果。
第一組
壓測結果:

10w請求數 200用戶
可以看見傳統的SpringMVC方式已經有阻塞了,最長的一次請求1107ms,但是整體性能基本一致,因為200個線程剛好是tomcat的線程池最大默認數。
第二組
ab -n100000 -c500 http://127.0.0.1:8080/hello1?id=1ab -n100000 -c500 http://127.0.0.1:8080/hello2?id=1ab -n100000 -c500 http://127.0.0.1:8080/hello3?id=1
壓測結果:

10w請求 500用戶
500用戶請求時候可以看到hello3接口的響應時間已經是hello1和hello2兩個接口響應時間的2倍以上了,但是基於project reactor響應編程開發方式的響應時間依舊和200用戶一致。
我們繼續將用戶數加到1000。
第三組
ab -n100000 -c1000 http://127.0.0.1:8080/hello1?id=1ab -n100000 -c1000 http://127.0.0.1:8080/hello2?id=1ab -n100000 -c1000 http://127.0.0.1:8080/hello3?id=1
壓測結果:

10w請求 1000用戶
我們發現基於project reactor開發的接口響應時間依舊堅挺,傳統SpringMVC方式開發的接口90%響應時間已經高達500ms了。

大家可以發現hello1和hello2兩個接口的實現方式其實是一致的,無非是自己定義一個Scheduler還是用reactor默認的Scheduler,如果大家點進去看源碼其實是一個意思,所以在性能上一致保持一致也是合理的,本質上都是無所不在的線程池:

至此我們就完成了在tomcat容器下的兩種不同方式的接口開發以及得到相應的性能壓測數據。
netty容器下代碼演示
將pom.xml中的spring-boot-starter-web依賴換為webflux依賴即可:

webflux依賴
還是剛剛那三個接口,啟動項目可以看到控制台有如下日志輸出:
代表我們這是一個基於Netty的web服務。
這里我們直接壓10w請求,1000用戶:
ab -n100000 -c1000 http://127.0.0.1:8080/hello1?id=1ab -n100000 -c1000 http://127.0.0.1:8080/hello2?id=1ab -n100000 -c1000 http://127.0.0.1:8080/hello3?id=1
壓測結果:

netty下壓測10w請求1000用戶
再和tomcat下同一壓測參數進行對比:

tomcat下壓測10w請求1000用戶
是不是發現netty的性能比tomcat更加優越?99%的請求在149ms即可完成。如果大家自己實操的話也會發現吞吐量也會較tomcat有大幅度的提升。
總結
我們始終都在不遺余力的追求如何開發一個高並發、低延遲的接口。
通過本文實操以及linux服務器下長時間的壓測,可以驗證的是我們可以使用WebFlux來替代SpringMVC,從而獲取更好的性能,更高的並發。如果你還和我一樣,對WebFlux還一知半解,那么從今天起開始學習起來吧。