RxJava VS Reactor

隨著web應(yīng)用的發(fā)展,人們提出了響應(yīng)式的概念,在應(yīng)用高負載,高并發(fā)的時候仍然有良好的用戶體驗,能夠盡可能的實時返回數(shù)據(jù)。

The need for a non-blocking web stack to handle concurrency with a small number of threads and scale with fewer hardware resources. Servlet 3.1 did provide an API for non-blocking I/O.

意思是使用更少的線程數(shù)和更少的硬件資源來處理大量的并發(fā)請求。

目前市場上比較流行的有幾種,RxJava,Akka,Vert.x,Reactor。最常使用的兩種框架,并且實現(xiàn)了響應(yīng)式編程規(guī)范的是RxJava和Reactor。

兩者之間有什么區(qū)別呢?

API -> Reactor

FlowableFluxAPI很相似都支持,ReactiveX常見的那些操作符。map,filter,flatmap等等,具體操作符列表:http://reactivex.io/documentation/operators.html

在Java版本上:

  • RxJava2.x必須至此Java 6,因為它Rxjava在安卓中用的很多
  • Reactor則至少要求Java 8. 其內(nèi)部利用了很多新版Java的特性。并且還可以方便的轉(zhuǎn)換為:CompletableFuturejava.util.stream.Stream,Optional

Reactor勝出一票

Checked exceptions -> RxJava

  • Reactor使用Java標(biāo)準的functional類型,如java.util.function.Function
  • RxJava使用自己設(shè)計的函數(shù)類型。io.reactivex.functions.Function

對于JDK自帶的Function,checked exception則不能編譯通過,效果如下圖。使用Reactor的時候必須要處理這些異常。

這一點設(shè)計的好壞上,看用戶習(xí)慣,但RxJava體驗上可能更好一些,用戶選擇是否要捕獲異常,Reactor強制捕獲異常。

image-20200113135725803
image-20200113135702010

RxJava勝出0.5票

類型 -> RxJava

Reactor只支持,Mono和Flux類型,而RxJava支持Completable,MayBe,Single,Observable,Flowable。

其中Mono和MayBe對應(yīng),F(xiàn)lowable和Flux對應(yīng)。Reactor不支持其它的類型,也就意味著在一些場景下Reactor并不能很好的支持。

  • 難道Mono一定要發(fā)射一個值?能不能不發(fā)射值
  • 能不能不想要背壓的支持?

在各種常見的處理上,RxJava處理的歧義比Reactor更少一些,并且支持更多的類型。

RxJava勝出一票

Testing -> Reactor

在多線程程序測試上,我們可能想要使用一個虛擬的線程調(diào)度器來模擬時鐘。RxJava提供了TestScheduler,但是可能會出現(xiàn)多次傳遞TestScheduler的場景,這個時候代碼就更容易陷入一團亂。

對于Reactor則是使用了withVirtualTime,底層會自動的進行替換,提升代碼的可讀性。

Reactor勝出0.5票

Debugging -> Reactor

Reactor添加了一個很好的調(diào)試特性:

Hooks.onOperatorDebug();

在應(yīng)用之前加上這一行代碼,可以跟蹤數(shù)據(jù)流的流動,看一個例子。

public class FluxDemo {
    public static void main(String[] args) {

        Hooks.onOperatorDebug();

        Mono<Long> totalTxtSize = Flux
                .just("/tmp", "/home", "/404")
                .map(File::new)
                .concatMap(file -> Flux.just(file.listFiles()))
                .filter(File::isFile)
                .filter(file -> file.getName().endsWith(".txt"))
                .map(File::length)
                .reduce(0L, Math::addExact);

        totalTxtSize.subscribe(System.out::println);
    }
}

不加Hooks調(diào)試。

image-20200113141212664

加上Hooks調(diào)試:

image-20200113141257216

響應(yīng)式編程在調(diào)試的時候增加了一定的難度,而Reactor帶來的特性一定程度上減輕了困難。

Reactor勝出一票

Spring支持 -> Reactor

Reactor本身是Spring開發(fā)人員弄出來的東西,可以與Spring無縫集成,當(dāng)前Spring新推出的Spring Webflux更是基于Reactor。

作為Java開發(fā)人員,Spring可以說是每日都要去使用的東西,Reactor都得到了官方的支持,為什么要使用RxJava呢?

Reactor勝出一票

Android開發(fā) -> RxJava

RxJava在安卓開發(fā)者中非常的流行,優(yōu)雅的解決了兩個問題,并且現(xiàn)在有RxAndroid的庫可以使用:

  • 避免了UI的事件回調(diào)地獄,將用戶UI事件建模為事件流
  • 容易的切換線程,避免了IO線程運行在UI線程上

目前安卓開發(fā)者只能選擇RxJava,并且RxJava在Android上已經(jīng)運行的很穩(wěn)定。

RxJava勝出一票

成熟度 -> RxJava

RxJava目前相比與Reactor更加成熟并且得到市場的認可,參考安卓,其目前被使用的時間更久,關(guān)于RxJava的書籍更多,并且也有很多的響應(yīng)式框架是基于RxJava來做的。

成熟度上目前RxJava勝出一票

最后

兩者不相上下

  • 如果是Web開發(fā),可以考慮使用Reactor,畢竟Spring的親兒子,而且Reactor使用了最新版的一些Java特性,效率上,安全性上,稍微好一點。
  • 如果是Android開發(fā),那么選擇RxJava,因為RxJava對Android的支持一直都很好
  • 如果現(xiàn)在已經(jīng)在使用兩種中的其一了,那么繼續(xù)使用,無需更換

參考:

https://www.reactivesystems.eu/2017/01/31/things-i-wish-i-knew-when-i-started-building-reactive-systems.html

https://www.javacodegeeks.com/2018/08/frameworks-toolkits-make-java-reactive-rxjava-spring-reactor-akka-vert-x-overview.html

https://www.nurkiewicz.com/2019/02/rxjava-vs-reactor.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容