隨著web應(yīng)用的發(fā)展寸痢,人們提出了響應(yīng)式的概念痴柔,在應(yīng)用高負(fù)載隧饼,高并發(fā)的時候仍然有良好的用戶體驗(yàn)硝枉,能夠盡可能的實(shí)時返回數(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磕潮。最常使用的兩種框架翠胰,并且實(shí)現(xiàn)了響應(yīng)式編程規(guī)范的是RxJava和Reactor。
兩者之間有什么區(qū)別呢自脯?
API -> Reactor
Flowable
和Flux
API很相似都支持之景,ReactiveX常見的那些操作符。map
,filter
,flatmap
等等膏潮,具體操作符列表:http://reactivex.io/documentation/operators.html
在Java版本上:
- RxJava2.x必須至此Java 6锻狗,因?yàn)樗黂xjava在安卓中用的很多
- Reactor則至少要求Java 8. 其內(nèi)部利用了很多新版Java的特性。并且還可以方便的轉(zhuǎn)換為:
CompletableFuture
焕参,java.util.stream.Stream
轻纪,Optional
Reactor勝出一票
Checked exceptions -> RxJava
- Reactor使用Java標(biāo)準(zhǔn)的functional類型,如
java.util.function.Function
- RxJava使用自己設(shè)計的函數(shù)類型叠纷。
io.reactivex.functions.Function
對于JDK自帶的Function刻帚,checked exception則不能編譯通過,效果如下圖涩嚣。使用Reactor的時候必須要處理這些異常崇众。
這一點(diǎn)設(shè)計的好壞上,看用戶習(xí)慣缓艳,但RxJava體驗(yàn)上可能更好一些,用戶選擇是否要捕獲異常看峻,Reactor強(qiáng)制捕獲異常阶淘。
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
的場景,這個時候代碼就更容易陷入一團(tuán)亂歪今。
對于Reactor則是使用了withVirtualTime
嚎幸,底層會自動的進(jìn)行替換,提升代碼的可讀性彤委。
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線程運(yùn)行在UI線程上
目前安卓開發(fā)者只能選擇RxJava或悲,并且RxJava在Android上已經(jīng)運(yùn)行的很穩(wěn)定孙咪。
RxJava勝出一票
成熟度 -> RxJava
RxJava目前相比與Reactor更加成熟并且得到市場的認(rèn)可,參考安卓巡语,其目前被使用的時間更久翎蹈,關(guān)于RxJava的書籍更多,并且也有很多的響應(yīng)式框架是基于RxJava來做的男公。
成熟度上目前RxJava勝出一票
最后
兩者不相上下
- 如果是Web開發(fā)荤堪,可以考慮使用Reactor,畢竟Spring的親兒子,而且Reactor使用了最新版的一些Java特性逞力,效率上曙寡,安全性上,稍微好一點(diǎn)寇荧。
- 如果是Android開發(fā)举庶,那么選擇RxJava,因?yàn)镽xJava對Android的支持一直都很好
- 如果現(xiàn)在已經(jīng)在使用兩種中的其一了揩抡,那么繼續(xù)使用户侥,無需更換
參考: