随着web应用的发展,人们提出了响应式的概念,在应用高负载,高并发的时候仍然有良好的用户体验,能够尽可能的实时返回数据。
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.
意思是使用更少的线程数和更少的硬件资源来处理大量的并发请求。
目前市场上比较流行的有几种,RxJava,Akka,Vert.x,Reactor。最常使用的两种框架,并且实现了响应式编程规范的是RxJava和Reactor。
两者之间有什么区别呢?
API -> Reactor
Flowable
和Flux
API很相似都支持,ReactiveX常见的那些操作符。map
,filter
,flatmap
等等,具体操作符列表:http://reactivex.io/documentation/operators.html
在Java版本上:
- RxJava2.x必须至此Java 6,因为它Rxjava在安卓中用的很多
- Reactor则至少要求Java 8. 其内部利用了很多新版Java的特性。并且还可以方便的转换为:
CompletableFuture
,java.util.stream.Stream
,Optional
Reactor胜出一票
Checked exceptions -> RxJava
- Reactor使用Java标准的functional类型,如
java.util.function.Function
- RxJava使用自己设计的函数类型。
io.reactivex.functions.Function
对于JDK自带的Function,checked exception则不能编译通过,效果如下图。使用Reactor的时候必须要处理这些异常。
这一点设计的好坏上,看用户习惯,但RxJava体验上可能更好一些,用户选择是否要捕获异常,Reactor强制捕获异常。
RxJava胜出0.5票
类型 -> RxJava
Reactor只支持,Mono和Flux类型,而RxJava支持Completable
,MayBe
,Single
,Observable
,Flowable
。
其中Mono和MayBe对应,Flowable和Flux对应。Reactor不支持其它的类型,也就意味着在一些场景下Reactor并不能很好的支持。
- 难道Mono一定要发射一个值?能不能不发射值
- 能不能不想要背压的支持?
在各种常见的处理上,RxJava处理的歧义比Reactor更少一些,并且支持更多的类型。
RxJava胜出一票
Testing -> Reactor
在多线程程序测试上,我们可能想要使用一个虚拟的线程调度器来模拟时钟。RxJava提供了TestScheduler
,但是可能会出现多次传递TestScheduler
的场景,这个时候代码就更容易陷入一团乱。
对于Reactor则是使用了withVirtualTime
,底层会自动的进行替换,提升代码的可读性。
Reactor胜出0.5票
Debugging -> Reactor
Reactor添加了一个很好的调试特性:
Hooks.onOperatorDebug();
在应用之前加上这一行代码,可以跟踪数据流的流动,看一个例子。
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调试。
加上Hooks调试:
响应式编程在调试的时候增加了一定的难度,而Reactor带来的特性一定程度上减轻了困难。
Reactor胜出一票
Spring支持 -> Reactor
Reactor本身是Spring开发人员弄出来的东西,可以与Spring无缝集成,当前Spring新推出的Spring Webflux更是基于Reactor。
作为Java开发人员,Spring可以说是每日都要去使用的东西,Reactor都得到了官方的支持,为什么要使用RxJava呢?
Reactor胜出一票
Android开发 -> RxJava
RxJava在安卓开发者中非常的流行,优雅的解决了两个问题,并且现在有RxAndroid的库可以使用:
- 避免了UI的事件回调地狱,将用户UI事件建模为事件流
- 容易的切换线程,避免了IO线程运行在UI线程上
目前安卓开发者只能选择RxJava,并且RxJava在Android上已经运行的很稳定。
RxJava胜出一票
成熟度 -> RxJava
RxJava目前相比与Reactor更加成熟并且得到市场的认可,参考安卓,其目前被使用的时间更久,关于RxJava的书籍更多,并且也有很多的响应式框架是基于RxJava来做的。
成熟度上目前RxJava胜出一票
最后
两者不相上下
- 如果是Web开发,可以考虑使用Reactor,毕竟Spring的亲儿子,而且Reactor使用了最新版的一些Java特性,效率上,安全性上,稍微好一点。
- 如果是Android开发,那么选择RxJava,因为RxJava对Android的支持一直都很好
- 如果现在已经在使用两种中的其一了,那么继续使用,无需更换
参考: