- Java編程方法論:響應式RxJava與代碼設計實戰
- 知秋
- 2968字
- 2019-09-20 15:06:18
1.4 響應式開發工具庫
已經有很多工具庫實現了響應式流的標準,包括Akka、Reactor、RxJava、Streams、Vert.x等。下面簡單介紹幾種,在后面的章節中我會重點講解RxJava(關于Reactor,會在本系列叢書的另一本書中具體講解)。
1.4.1 RxJava簡介
通過官方GitHub可知,RxJava是使用Java語言開發的專門針對JVM的一種響應式擴展工具,通過它可以輕松地在服務器端實現并發操作。RxJava的目的就是處理客戶端越來越復雜的請求,在服務器端通過并行計算快速地響應請求。
接下來,我們開始了解RxJava到底是怎么一回事,作為數據的消費者,我們會對獲得的數據做出各種反應。有句話說得好,“跳出三界外,不在五行中”,在我們以旁觀者的視角來看這件事的時候,其實它就是一個觀察者模式的實際體現。RxJava下的響應式編程其實就是基于影院里的電影(Observable)提供的內容(生產者數據)傳播給訂閱者,然后訂閱者做出相應的反應。
結合上面的場景,下面對RxJava所涉及的要點進行解釋。
● Observable:表示數據源,Observable會發出一定數量的元素,發送可能會成功,也可能在這個過程中出現狀況而失敗。從電影院的場景可以知道,同一時間Observable可以有多個訂閱者。
● Observer或Subscriber:表示訂閱者,通過監聽Observable來消費Observable所發送的元素。
● Methods:表示一系列操作API,對下發數據進行加工整合。
● onNext:在一個元素被Observable發送出去的時候,通過該方法可以調用每一個訂閱者。
● onComplete:在Observable成功發送完所有數據后,會調用這個方法來收尾。
● onError:當Observable發送數據的過程中出現錯誤的狀況時,會調用這個方法結束發送并返回一個error事件。
RxJava所帶來的好處主要如下。
● 允許我們進行一系列的異步操作。
● 有時為了跟蹤狀態,我們會通過一個原子類變量保存之前計算的值。我們無須專門使用原子類來跟蹤狀態,因為RxJava中已經封裝了這些操作。
● RxJava提供了一個在整個執行過程中發生錯誤時的處理途徑。
1.4.2 Reactor簡介
Spring 5官方文檔提到,其通過Reactor的支持,在服務器端獲得了更高的性能和更快的響應速度。Spring WebFlux作為新一代的Web開發框架,以Reactor作為基礎框架進行異步編程的開發,從而可以使我們寫出性能更好的Web應用程序。如果大家看過我博客中關于Spring 5源碼分析的系列文章,就可以知道Spring MVC框架的整個運行過程其實使用了事件驅動(Event-Driven)模式,而Reactor自身的設計也使用了這個模式。參考前面的電影院場景,當電影的畫面和聲音傳到你的眼睛和耳朵中時,會引發你喜怒哀樂的情緒反應。再形象一點,在拳擊選手一個直拳要打到對方選手臉上的時候,對方選手會躲閃。電影的畫面和拳擊選手的直拳動作都是一種事件的表現,根據事件做出相應處理的整個過程就是所謂的事件驅動。在Spring里,這就相當于我們的后臺服務器接收事件請求,通過multicaster多路分發器來分發給相應的監聽器(Listener),最后由監聽器里定義的相應的handler來做具體處理。整個過程大概就是這樣的。
知道了上面的這些內容,通過使用Reactor,我們寫出的程序就可以按照事件驅動的模式很輕易地異步運行了。
1. Reactor的優點
Reactor支持完全無阻塞,其主要的目標之一就是解決傳統Web開發方案對于異步支持的各種弊病。它提供了十分有效的途徑來支持背壓。它還有以下優點。
● 豐富的API,可以對數據流進行操作。
● 提供了一種可讀性更強的代碼書寫方式,使我們所寫的代碼可以更方便地得到維護。
● 與流相同,無消費,不執行。
● 消費者具備發信號通知生產者元素按需下發的能力(RxJava同樣具備)。
2. Reactor的核心功能
Reactor項目的主要模塊是reactor-core,這是一個專門用于支持響應式流規范的類庫,其支持Java 8及后續版本。通過查看Reactor API,可知它和RxJava很像。Reactor 3是Reactor 2和RxJava的核心貢獻開發者一起完成的一個混合版本,這也是本章把這幾個東西放在一起介紹,然后分章講解的很重要的原因,因為這樣更易于理解。
Reactor與RxJava有相同的Publisher、Subscriber、Subscription和Processor核心接口。這里只簡單介紹Publisher最常用的兩個實現Mono和Flux,以及相關的操作符。
● Mono:表示一個特殊的Publisher,它可以發送0個或1個元素。
● Flux:表示一個特殊的Publisher,它可以發送0到n個元素。
● 操作符:元素在從Publisher發送給訂閱者之前,可能會需要進行一些處理,包括轉換、過濾操作等。
1.4.3 MongoDB簡介
在后面的實戰開發中,我們可能會用到MongoDB,官方提供的MongoDB Reactive Streams Java版本的驅動包API可以對MongoDB進行異步流處理,而且是無阻塞支持背壓的。這里只是提一下,說明我們的數據庫操作層面也開始做到了對響應式流API標準的支持。
1.4.4 響應式項目用例
前面說了那么多,大家可能依然有點不明白,那么為了更好地理解響應式系統(Reactive System),我們看看它與傳統項目的不同之處。
以我們生活中的股票場景為例,我們需要看到股票信息的實時動態展示。這時我們會打開并保持一個頁面,這個頁面可以實時顯示股票信息。開發人員需要做的是,將最新的數據更新到這個股票展示頁面上。作為股民,面對的是“差之毫厘,失之千里”的局面。對他們來說,數據刷新得越及時,對決策越有利(在這里,我們只從響應式的角度來考慮這個問題,現實項目中會有基于WebSocket的實現,Spring MVC中也有SSE的實現)。
1. 傳統開發模式
根據以往的開發經驗,我們會主動地檢查股票價格有沒有變化,如果有變化,就從后臺拉取最新的數據。如圖1-1所示的流程圖就代表著傳統開發模式。

圖1-1
在傳統開發模式下,一旦開始渲染訪問頁面,就會每隔一段時間(圖1-1中是1分鐘)發送AJAX請求到后臺的查詢服務去請求股票價格數據。使用這種方式,無論股票價格是否真的發生變化,都會去請求,但無法保證股票價格的變化會被立刻傳遞到Web頁面上。
2. 響應式開發模式
響應式開發模式通過事件驅動的方式將各個組件連接到一起,以實現在事件發生時其他組件可以立即進行響應。
也就是說,在加載股票價格頁面后,這個頁面會有一個專屬ID注冊到股票查詢服務上。一旦使股票價格發生變化的事件產生,這個事件(Event)就會觸發響應,最新的股票價格就會在Web頁面上進行更新顯示。如圖1-2所示說明了整個流程。

圖1-2
可以看到,響應式開發模式一般包括下面3個步驟。
(1)訂閱(Subscribing)事件。
(2)事件的發生與傳播。
(3)解除訂閱。
在股票價格頁面初始化加載的時候,其中有一個動作就是訂閱當前使股票價格發生變化的事件源,可以認為事件源是消息中間件里的主題(Topic)(或者是我們訂閱的一個RSS主題),而不同的響應式框架會有不同的具體方式,使用消息中間件也可以實現訂閱。
在我們所關注的某只股票價格發生變化的時候,一個新的事件就會產生并分發給這個事件的訂閱者。我們的Web頁面會及時地接收并更新股票價格數據。而一旦Web頁面關閉或者刷新,一個解除訂閱的請求就會被發送至后臺。
3. 傳統開發模式和響應式開發模式的比較
可以看到,傳統開發模式是比較簡單的,而響應式開發模式需要我們實現一個訂閱和事件傳播鏈。如果事件的傳播需要跨項目,也就是涉及其他項目,那么就可能會使用到消息中間件,這將會變得復雜,其并不屬于本書的范圍,此處不做討論。
在傳統開發模式中,更新股票價格頁面主要是基于盲目的主動拉取來實現的,前端根本就不知道會不會有數據發生變化。這也就意味著無論后臺數據有沒有發生變化,前端都需要定時從后臺拉取一次數據。而在響應式開發模式中,一旦注冊訂閱了價格變動事件,那么只有這只股票的價格發生變化才會觸發一系列的操作,這樣明顯提高了程序性能和用戶體驗。
在傳統開發模式中,這個例子中線程的生命周期會比較長,這也就意味著該線程所使用的資源在這個過程中會被線程鎖定。考慮到同一時刻服務器會接收大量的請求,這樣勢必會造成更多的線程相互爭奪資源。在響應式開發模式中,線程生存的時間短,這也就意味著爭奪資源的情況較少,后面在本書中會針對類似場景進行相應的實戰Demo展示。
- 摩登創客:與智能手機和平板電腦共舞
- Dynamics 365 Application Development
- Microsoft Dynamics 365 Extensions Cookbook
- ASP.NET動態網頁設計教程(第三版)
- Instant QlikView 11 Application Development
- TypeScript圖形渲染實戰:基于WebGL的3D架構與實現
- 21天學通C++(第6版)
- C程序設計案例教程
- JAVA程序設計實驗教程
- Mastering Android Development with Kotlin
- 低代碼平臺開發實踐:基于React
- SciPy Recipes
- Illustrator CS6設計與應用任務教程
- AutoCAD基礎教程
- MATLAB 2020 GUI程序設計從入門到精通