只有光頭才能變強。html
文本已收錄至個人GitHub精選文章,歡迎Star:https://github.com/ZhongFuCheng3y/3yreact
回顧一下上篇我對WebFlux的入門,若是沒讀過的同窗建議讀一下再來看本篇文章,上一篇文章花了我不少的心血~~git
開局再來一張圖,內容全靠編:github
這篇主要寫寫我初學時對WebFlux的一些疑問,不知道你們在看上一篇文章的時候有沒有相應的問題呢?web
此次學WebFlux主要的動力是公司組內分享,寫了一個PPT,有須要的同窗在個人公衆號(Java3y)下回復「PPT」便可獲取。spring
相信有過相關了解的同窗都知道,Servlet 3.1
就已經支持異步非阻塞了。sql
咱們能夠以自維護線程池的方式實現異步數據庫
1@WebServlet(value = "/nonBlockingThreadPoolAsync", asyncSupported = true) 2public class NonBlockingAsyncHelloServlet extends HttpServlet { 3 4 private static ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 200, 50000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100)); 5 6 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 7 8 AsyncContext asyncContext = request.startAsync(); 9 10 ServletInputStream inputStream = request.getInputStream(); 11 12 inputStream.setReadListener(new ReadListener() { 13 @Override 14 public void onDataAvailable() throws IOException { 15 16 } 17 @Override 18 public void onAllDataRead() throws IOException { 19 executor.execute(() -> { 20 new LongRunningProcess().run(); 21 22 try { 23 asyncContext.getResponse().getWriter().write("Hello World!"); 24 } catch (IOException e) { 25 e.printStackTrace(); 26 } 27 asyncContext.complete(); 28 29 }); 30 } 31 32 @Override 33 public void onError(Throwable t) { 34 asyncContext.complete(); 35 } 36 }); 37 38 39 } 40 41}
流程圖以下:編程
異步非阻塞的圖api
上面的例子來源:
簡單的方式,咱們還可使用JDK 8 提供的CompletableFuture
類,這個類能夠方便的處理異步調用。
1protected void doGet(HttpServletRequest request, 2 HttpServletResponse response) throws ServletException, IOException { 3 long t1 = System.currentTimeMillis(); 4 5 // 開啓異步 6 AsyncContext asyncContext = request.startAsync(); 7 8 // 執行業務代碼(doSomething 指的是處理耗費時間長的方法) 9 CompletableFuture.runAsync(() -> doSomeThing(asyncContext, 10 asyncContext.getRequest(), asyncContext.getResponse())); 11 12 System.out.println("async use:" + (System.currentTimeMillis() - t1)); 13}
要處理複雜的邏輯時,不管是回調或 CompletableFuture在代碼編寫上都會比較複雜(代碼量大,不易於看懂),而WebFlux使用的是Reactor響應式流,裏邊提供了一系列的API供咱們去處理邏輯,就很方便了。
回調地獄
更重要的是:
回調/CompletableFuture
要簡潔和易編寫。無縫與SpringMVC的技術使用
值得一提的是:
若是Web容器使用的是Tomcat,那麼就是使用Reactor橋接的servlet async api
若是Web容器是Netty,那麼就是使用的Netty,天生支持Reactive官方的推薦是使用Netty跑WebFlux
咱們從上篇文章中就發現,瀏覽器去調用處理慢的接口,不管是該接口是同步的,仍是說是異步的,返回到瀏覽器的時間都是一致的。
官網也說了:
Reactive and non-blocking generally do not make applications run faster
使用異步非阻塞的好處就是:
The key expected benefit of reactive and non-blocking is the ability to scale with a small, fixed number of threads and less memory.That makes applications more resilient under load, because they scale in a more predictable way
好處:只須要在程序內啓動少許線程擴展,而不是水平經過集羣擴展。異步可以規避文件IO/網絡IO阻塞所帶來的線程堆積。
下面來看一下針對相同的請求量,同步阻塞和異步非阻塞的吞吐量和響應時長對比:
吞吐量和RT對比
注:
-->
將請求委派給另外一個線程去作處理Spring WebFlux在應對高併發的請求時,藉助於異步IO,可以以少許而穩定的線程處理更高吞吐量的請求,尤爲是當請求處理過程若是由於業務複雜或IO阻塞等致使處理時長較長時,對比更加顯著。
WebFlux須要非阻塞的業務代碼,若是阻塞,須要本身開線程池去運行。WebFlux什麼場景下能夠替換SpringMVC呢?
SpringMVC和WebFlux更多的是互補關係,而不是替換。阻塞的場景該SpringMVC仍是SpringMVC,並非WebFlux出來就把SpringMVC取代了。
SpringMVC和WebFlux
若是想要發揮出WebFlux的性能,須要從Dao到Service,所有都要是Mono和Flux,目前官方的數據層Reactive框架只支持Redis,Mongo等幾個,沒有JDBC。
目前對於關係型數據庫,Pivotal團隊開源出R2DBC(Reactive Relational Database Connectivity),其GitHub地址爲:
目前R2DBC支持三種數據源:
總的來講,由於WebFlux是響應式的,要想發揮出WebFlux的性能就得將代碼全改爲響應式的,而JDBC目前是沒支持的(至少MySQL還沒支持),而響應式的程序很差調試和編寫(相對於同步的程序),因此如今WebFlux的應用場景仍是相對較少的。
因此,我認爲在網關層用WebFlux比較合適(原本就是網絡IO較多的場景)
如今再回來看Spring官網的圖,是否是就更親切了?
Spring官網介紹圖
參考資料:
前面也提到了,WebFlux提供了兩種模式供咱們使用,一種是SpringMVC 註解的,一種是叫Functional Endpoints
的
Lambda-based, lightweight, and functional programming model
總的來看,就是配合Lambda和流式編程去使用WebFlux。若是你問我:有必要學嗎?其實我以爲能夠先放着。我認爲如今WebFlux的應用場景仍是比較少,等真正用到的時候再學也不是什麼難事,反正就是學些API嘛~
有Lambda表達式和Stream流的基礎,等真正用到的時候再學也不是啥問題~
如下是經過註解的方式來使用WebFlux的示例:
經過註解的方式來使用WebFlux
如下是經過Functional Endpoints
的方式來使用WebFlux的示例:
路由分發器,至關於註解的GetMapping…
路由分發器
UserHandler,至關於UserController:
UserHanler
總的來講,由於WebFlux是響應式的,要想發揮出WebFlux的性能就得將代碼全改爲響應式的,而JDBC目前是沒支持的(至少MySQL還沒支持),而響應式的程序很差調試和編寫(相對於同步的程序),老項目也不太可能把依賴直接升上Spring5.0,因此如今WebFlux的應用場景仍是相對較少的(我的以爲)。
網關層用WebFlux比較合適(原本就是網絡IO較多的場景)
此次學WebFlux主要的動力是公司組內分享,寫了一個PPT,有須要的同窗在個人公衆號(Java3y)下回復「PPT」便可獲取。
本已收錄至個人GitHub精選文章,歡迎Star:https://github.com/ZhongFuCheng3y/3y
樂於輸出乾貨的Java技術公衆號:Java3y。公衆號內有300多篇原創技術文章、海量視頻資源、精美腦圖,關注便可獲取!
轉發到朋友圈是對我最大的支持!
很是感謝人才們能看到這裏,若是這個文章寫得還不錯,以爲「三歪」我有點東西的話 求點贊 求關注️ 求分享👥 求留言💬 對暖男我來講真的 很是有用!!!
創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!