1. 程式人生 > 程式設計 >Spring WebFlux學習筆記:1概述

Spring WebFlux學習筆記:1概述

Spring Flux是一個完全非阻塞, 非同步的web框架.支援和spring mvc接近的註解配置controler,還支援functional endpoint風格的配置. spring-webflux 依賴於reactor-core,以此來提供非同步流支援. 即使只使用mvc,也可以使用非同步的webclient,另外Spring WebFlux是可以和Mvc同時存在於一個專案的.
非同步非阻塞在效能上真正的好處是, 在高請求的情況下, 更少的記憶體, 更少的執行緒數量。
在響應式的技術體系中,有兩個非常重要的概念: flux和mono 簡單的理解: 代表一種當前不存在,在未來某個時間可以通過其中資料來獲取的一種抽象. 其中Mono代表可以獲取0個或1個資料,Flux則是多個資料.

1.1 什麼是reactive?

reactive就是non blocking. 支援back pressure(傳送的資料不超過服務端的處理能力), 這個是需要在費阻塞程式設計中處理的問題. reactive stream是致力於解決這個問題的規範. 但是reactive stream 太底層, 應用需要更加高層, 功能更加豐富的api,Spring Flux正是扮演了這個角色.

1.2 程式設計模型

1 類似mvc的註解模型 2 函式式endpoint


1.3 關於是否採用flux的考量


不採用flux的考慮: 加入原來的應用使用spring mvc編寫, 而且沒有什麼問題。 那麼就沒有必要轉換未flux. 同步的程式碼容易編寫, 理解和除錯。
假如應用依賴阻塞式的類庫, 如jdbc,jpa或者阻塞式的網路io,那麼其實採用flux沒有什麼意義。
非阻塞, 函式式和宣告式程式設計的學習曲線並不平滑, 假如原來的架構是阻塞式的, 大範圍轉移是不必要的。
即使不完全使用flux,使用非同步的webClient的理由: 可以採用非同步的webClient去呼叫遠端服務, 如果當前應用是有很多這種轉發呼叫, 那麼會有很大地助益. 這種非同步的客戶端同時可以喚起的請求可以非常多,並且只需要少量的執行緒.

如果決定要用非同步的或者函式式的程式設計, 選擇flux的理由: spring flux,提供伺服器底層的選擇(netty,servlet3.1+,tomcat,jetty,undertow等等), 程式設計模式的選擇(接近mvc的註解controller風格, 函式式風格),一些非同步庫(Reactor,RxJava等)
輕量的函式式web框架




1.4 伺服器

支援netty,undertow等伺服器。 預設的伺服器是netty spring flux提供統一的高層api來遮蔽這些低層api的不同. 假如使用tomcat作為伺服器, 那麼如果在專案中使用servlet api,其實並不是直接使用的, 而是經過一系列低層的adapter轉換來間接使用的。

1.5 效能

非同步非阻塞一般來說並不會使應用跑得更快(除了並行用webvlient請求遠端服務這種情況), 反而會因為需要做更多的工作, 而增加少量的處理時間。
非同步非阻塞的關鍵價值, 是能更好的基於少量固定數目的執行緒和少量的記憶體下進行伸縮(這裡的伸縮是指處理的資料規模的放大和縮小)。 這讓程式更加有彈性, 因為它能以更加可預測的方式進行伸縮。(這一句我不理解) 假如應用有一些如網路通訊等高延遲的操作, 那麼這種好處會很明顯, 甚至可以非常誇張。
非同步非阻塞在效能上真正的好處是, 在高請求的情況下, 更少的記憶體, 更少的執行緒數量(執行緒的建立和維持都是有開銷的)。

1.6 併發


併發模型

spring mvc假設一個請求的處理過程可能被執行緒阻塞, 所以使用一個比較大的執行緒池 flux假設請求的處理過程中沒有阻塞, 所以使用一個比較小的固定數量的執行緒來處理請求
假如需要在webflux呼叫阻塞的類庫, reactor庫和rxjava庫都有publish操作符, 可以將這種處理在其他的執行緒上繼續。 無論如何, 在flux中使用阻塞類庫是不被推薦的。

可變的狀態

將應用從維護可變狀態的執行緒安全中解放出來, 因為這些是會按序執行的

執行緒模型

對於一個沒有資料庫訪問的webflux,一般來說是一個執行緒作為server,和cpu數量一致的執行緒作為處理請求。 應用有webclient呼叫, 少數量固定數目的執行緒來給wecliwnt使用, 或者如果使用netty作為伺服器, 那麼複用請求執行緒。 Reactor和rxjava有Scheduler這種執行緒池, 當publishon這種操作發生時, 就會在使用這種執行緒的執行緒池。 這種執行緒池有兩種, 一種是專門處理計算複雜型的任務, 數量和cpu核數相關, 一種是專門處理io型別的任務, 這種執行緒的數量會比較多。




參考檔案: 

官方檔案: docs.spring.io/spring/docs…