Spring 5 WebFlux 性能測試

Java 世界對反應式編程抱有很高的期望。 根據 官方文檔 的描述,它使程序員能夠構建更具彈性,彈性,響應和消息驅動的應用程序。 簡而言之,它是一種更好,更快,更現代的模型,可以防止應用程序空閒。

Spring 5 通過結合基於 Project Reactor的 Spring 反應計劃,引入了一種新的響應式編程模型。 但它能完成這項工作嗎?

我們研究了Spring 提供的新功能,並對它進行了一次性能測試,測試結果請往下看,我想不會讓你失望的。

注意:我們的結果可能會在幾周/幾個月內改變。 實際上,截至目前,尚未發佈真實的 Spring 樣本,並且文檔不完整。 Spring 5 和 Spring Boot 2 仍在開發中(Spring Framework 5.0.0 RC3,Spring Boot 2.0.0.M2),Project Reactor 也在不斷髮展。 此外,社區的反饋仍然很少(JHipster,Spring,Reddit)。

What’s new in Spring 5?

Spring框架引入了很多新功能 。其中最重要的是反應式編程。

Spring MVC and Spring WebFlux

可能仍然有一些人可能試圖用舊的 Spring 4 技術進行反應式編程,如果你這樣做,那麼你肯定可能會遇到一些麻煩。 Spring 5 提供了一個易於使用的新模塊:spring-webflux。 它與它的兄弟 spring-mvc 做同樣的事情,但是它是一種響應式編程模型。 讓我們看看它是如何工作的吧。

WebFlux 主要圍繞兩個 Project Reactor 的類:Mono 和 Flux。

Mono 是 CompletableFuture 類型的反應等價物,允許以反應方式處理單個對象。 Flux 是多個對象的等價物。 它們像 Stream 一樣處理(準備好使用 lambda 表達式)。 因此,你可能會看到如下所示的代碼:

它們都是 Reactive Streams 規範的 Publisher 接口的實現,因此它們需要註冊到訂閱服務器以便數據開始流動。

幸運的是,基於註解的編程模型仍然是最新的,與 Spring MVC 的唯一區別是 REST 層的方法現在返回 Mono 或 Flux:

Spring 知道如何處理 Monos 或 Fluxs 。 它會自動將封裝的對象傳遞給前端。

關於與數據庫的通信,Spring 5 支持 Cassandra,CouchBase,MongoDB和 Redis 的反應驅動程序,它們可以跟 Spring Data 一起使用。

下面是操作 MongoDB 代碼例子

Our tests

Why?

反應式編程現在正在流行,當然,Pivotal 決定在邏輯上將其集成到 Spring 框架中,並承諾提供更好的性能和可擴展性。 可悲的是,沒有給出任何性能測試數據……

How?

我們通過在生產模式下對不同的 JHipster 生成的應用程序(MySQL,Mongo,Model……)進行壓力測試(使用Gatling)。

這些應用程序中的每一個都經過多次複製和修改,以確保我們的測試有豐富的測試數據,從而確保測試的正確性。

例如,對於MySQL應用程序,我們創建了四個類似的應用程序:

  • 使用 Spring 4 (因為你可以使用 JHipster 實際生成)
  • 使用 Spring 5 (僅遷移)
  • 使用 Spring 5 和反應式編程(在 REST 層上)
  • 使用 Spring 5 和反應式編程(僅在一個實體的 RestController 類上)

對於具有異步驅動程序的Mongo,我們創建了應用程序:

  • 使用Spring 4(因為你可以使用JHipster實際生成)
  • 使用Spring 5(僅遷移)
  • 使用Spring 5和反應式編程(在REST層上)
  • 使用Spring 5和反應式編程(僅在一個實體的RestController類上)
  • 使用Spring 5和實體上的反應式編程一直到存儲庫。

Spring允許程序員配置自己的調度程序(處理被動調用的線程池)。 因此,當使用反應式編程時,僅在 REST 層(而不是實體)上,我們嘗試了不同的調度程序:Schedulers.parallel()每個CPU核心使用一個線程,而Schedulers.elastic()動態創建線程。

每個測試包括同時啟動 Gatling 5000/10000/15000 用戶,每個用戶執行場景中描述的操作:

然後,我們可以通過比較時間或錯誤/崩潰來分析這些結果。

Our big configuration:

  • 機器1用作 Spring Boot 服務器和本地數據庫:i7-4790K 4GHz - 16Go - SSD - Ubuntu 16.04 64bits
  • 機器2用作加特林客戶端:i7-4790K 4GHz - 16Go - SSD - Ubuntu 16.04 64bits
  • Cisco SG100-24 24 端口千兆交換機
Spring 5 WebFlux 性能測試

configuration

Results

從 5000 個用戶的模擬生成了以下結果。 我們還使用 10000/15000/20000 用戶進行了測試,但由於錯誤數量很多,結果並不一致。

With a MySQL-based JHipster application:

(注意:下面的結果不包括場景中的暫停。)

Spring 5 WebFlux 性能測試

MySQL-based

當用戶在他的Gatling場景中出現錯誤時,他的模擬將停止。 因此,如果存在一些錯誤,則請求服務器的用戶較少,因此負載較低且時間更改。

錯誤可以有幾種:超時,達到數據庫連接的閾值,使用Spring創建/銷燬bean的併發問題,……

這些圖表顯示了用戶運行Gatling場景所需的總時間。

Spring 5 WebFlux 性能測試

MySQL-based2

Spring 5 WebFlux 性能測試

MySQL-based3

With a Mongo-based JHipster application:

Spring 5 WebFlux 性能測試

MySQL-based3

Spring 5 WebFlux 性能測試

MySQL-based3

Spring 5 WebFlux 性能測試

MySQL-based3

Regarding the execution times

我們可以看到,總體而言,Reactive 應用程序比“經典” Spring 應用程序慢。

對於MySQL,它是可預測的,因為數據庫在使用過程中設置了所有鎖,並且沒有官方的響應/異步驅動程序。

對於Mongo,有一堆完整的反應組件(驅動程序,存儲庫,……),但即便如此,性能也會更差。

此外,我們注意到Spring 4 和 Spring 5 之間的速度沒有明顯改善,即使沒有添加反應式編程。

Regarding scalability

關於可擴展性,Reactive 應用程序可以處理比Spring4 / Spring5 應用程序更少的用戶。
實際上,我們通過使用 Gatling 模擬5000,10000,15000和20000用戶注意到了這種差異。

從10000個用戶開始,我們在Reactive應用程序上有太多錯誤,通常超過40%的KO請求。

Conclusion

  • 我們的反應式應用程序沒有觀察到速度的提高(Gatling 的結果甚至略差)。
  • 關於用戶友好性,反應式編程不會添加大量新代碼,但它肯定是一種更復雜的編碼(和調試……)方式。 可能需要快速 Java 8 複習。
  • 目前的主要問題是缺乏文件。 這是我們生成測試應用程序的最大障礙,因此我們可能錯過了一個關鍵點。
  • 因此,我們建議不要在反應式編程上跳得太快並等待更多反饋。 Spring WebFlux 尚未證明其優於 Spring MVC 的優勢。

你可以在此存儲庫中找到我們的代碼:jhipster / webflux-jhipster 。

Gatling 結果可以在每個模塊根目錄的 gatling-results 目錄中找到。

原文鏈接

  • Spring 5 WebFlux: Performance tests


分享到:


相關文章: