隨著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
Flowable和FluxAPI很相似都支持,ReactiveX常見的那些操作符。map,filter,flatmap等等,具體操作符列表:http://reactivex.io/documentation/operators.html
在Java版本上:
- RxJava2.x必須至此Java 6,因為它Rxjava在安卓中用的很多
- Reactor則至少要求Java 8. 其內(nèi)部利用了很多新版Java的特性。并且還可以方便的轉(zhuǎn)換為:
CompletableFuture,java.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強制捕獲異常。


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)試。

加上Hooks調(diào)試:

響應(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ù)使用,無需更換
參考: