(2)响应式流——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》
前情提要: 什么是响应式编程

1.2 响应式流

上一节留了一个坑——为啥不用Java Stream来进行数据流的操作? 原因在于,若将其用于响应式编程中,是有局限性的。比如如下两个需要面对的问题:

  1. Web 应用具有I/O密集的特点,I/O阻塞会带来比较大的性能损失或资源浪费,我们需要一种异步非阻塞的响应式的库,而Java Stream是一种同步API。
  2. 假设我们要搭建从数据层到前端的一个变化传递管道,可能会遇到数据层每秒上千次的数据更新,而显然不需要向前端传递每一次更新,这时候就需要一种流量控制能力,就像我们家里的水龙头,可以控制开关流速,而Java Stream不具备完善的对数据流的流量控制的能力。

具备“异步非阻塞”特性和“流量控制”能力的数据流,我们称之为响应式流(Reactive Stream)。

目前有几个实现了响应式流规范的Java库,这里简单介绍两个:RxJavaReactor

要介绍RxJava,就不得不提ReactiveX(Reactive Extensions,Rx),它最初是LINQ的一个扩展,由微软的架构师Erik Meijer领导的团队开发,在2012年11月开源,Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx库支持.NET、JavaScript和C++,Rx近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,包括RxJS、RxJava等。

后来,Java社区的一些大牛凑到一起制定了一个响应式流规范。RxJava团队随后对1版本进行了重构,形成了兼容该响应流规范的RxJava 2。

Reactor是Pivotal旗下的项目,与大名鼎鼎的Spring是兄弟关系,因此是Spring近期推出的响应式模块WebFlux的“御用”响应式流。Reactor支持响应式流规范,与RxJava相比,它没有任何历史包袱,专注于Server端的响应式开发,而RxJava更多倾向于Android端的响应式开发。

在Java 9版本中,响应式流的规范被纳入到了JDK中,相应的API接口是java.util.concurrent.Flow

Spring WebFlux也是本系列文章后边的重点内容。由于WebFlux首选Reactor作为其响应式技术栈的一部分,我们下边也主要以Reactor为主,目前的版本是Reactor3。

我们继续回到主线,讨论“异步非阻塞”和“流量控制”。注意,本节请不必关注Reactor的代码细节,仅体会使用响应式流的“感觉”就好。

1.2.1 异步非阻塞

在如今互联网时代的大背景下,Web应用通常要面对高并发、海量数据的挑战,性能从来都是必须要考量的核心因素。

阻塞便是性能杀手之一。

从调用者和服务提供者的角度来看,阻塞、非阻塞以及同步、异步可以这么理解:

  • 阻塞和非阻塞反映的是调用者的状态,当调用者调用了服务提供者的方法后,如果一直在等待结果返回,否则无法执行后续的操作,那就是阻塞状态;如果调用之后直接返回,从而可以继续执行后续的操作,那可以理解为非阻塞的。
  • 同步和异步反映的是服务提供者的能力,当调用者调用了服务提供者的方法后,如果服务提供者能够立马返回,并在处理完成后通过某种方式通知到调用者,那可以理解为异步的;否则,如果只是在处理完成后才返回,或者需要调用者再去主动查询处理是否完成,就可以理解为是同步的。

举个例子,老刘买了个洗衣机,当他启动了洗衣机后如果一直在等待洗衣机工作结束好晾衣服,那他就是阻塞的;如果他启动洗衣机之后就去看电视了,估摸快洗完了就时不时来看看,那他就是非阻塞的,因为老刘可以去做另一件事。但老刘不能知道这洗衣机啥时候洗完/是否洗完,那么这台洗衣机就是同步方式工作的;老刘后来换了一台可以在洗完衣服播放音乐的洗衣机,这样就不用时不时来看了,虽然启动之后洗衣机不能立刻返回给老刘干净的衣服,但是可以在工作完成之后通知在看电视的老刘,所以新的洗衣机就是异步工作的。

Http服务本质上是对资源的操作,尤其是RESTful兴起之后,更是如此。所谓的资源,对应在服务器端就是文件和数据。

  • 文件方面,随着互联网基础设施的提升,Web 应用正在接纳、处理和传递越来越多的包括图片和音视频等形式在内的文件。文件的存取可能造成阻塞。
  • 数据方面,随着大数据技术的推进,互联网公司越来越热衷于收集来自用户的操作、位置、社会关系等等各种各样的信息。数据越来越具有流动性,数据量也显著增长。数据的存取也可能造成阻塞。
  • 此外,随着微服务架构的日趋火热,各个微服务之间的通信不再像“巨石型”应用中通过对象的引用和方法的调用,而是经由网络传输序列化的数据来实现,网络的延迟也可能造成阻塞。
  • 除了I/O方面的阻塞之外,一些复杂的业务逻辑由于处理时间比较长,也会造成调用者的阻塞。

多数人不认为阻塞是一个比较大的问题,至少觉得除了网络I/O之外,读写文件和数据库还是很快的,许多的开发者也一直在写阻塞的代码。那么我们就先来关注一下I/O的阻塞问题,对其严重性有一个直观感性的认识。

1.2.1.1 I/O到底有多慢?

很多情况下,在大的空间和时间维度上,数量级经常会大到超出我们的认知范畴,我们的直觉总是不可靠的。

一、举两个空间维度的例子:

在大的尺度上,印象中,银河系的中心位置群星闪耀,就像赶集一样:


但实际上,如果把恒星们缩小到沙粒的大小,那么密度也就相当于一个体育场有一两粒沙子。曾经看科幻片,总是担心光速飞行的飞船来不及拐弯或刹车撞到星球上,实际上,想要撞上才是相当不容易的。

而在小的尺度上,原子核具有原子绝大部分的质量,印象中,应该是这样的吧:

在这里插入图片描述

但实际上,如果把一个原子也放大到体育场那么大,原子核才仅仅相当于一个乒乓球那么大,空旷的很!

二、从时间维度上:

往大了说,如果地

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值