Spring 5 大力支持了 Reactive Programming(响应式开发),server 和 client 都可以使用这种开发模式,Spring 5 是基于 Reactor项目实现的。
简单来说,Reactive Programming 是一种非阻塞、事件驱动数据流的开发方案,使用函数式编程的概念来操作数据流,系统中某部分的数据变动后会自动更新其他部分,而且成本极低。
reactive streams 是非阻塞的,所以数据的处理过程中无需等待,对于系统的扩展性非常有帮助,因为工作线程不必等待其他资源,可以自由的处理更多的请求。
下面看一个例子,有助于更好的理解,例如我们要从数据库加载用户数据,然后把用户名形成一个新的集合。
① 传统方式
② 函数式处理集合数据流
③ 响应式
函数式比传统方式更加简洁,但如果数据库比较忙,那么我们的线程就被阻塞了,而响应式就可以解决这个问题,非阻塞,主线程不会捆绑在这个操作上,如果调用者也是响应式的,那么就形成了一个非阻塞的传播链条。
如果 web server 是响应式的,那么处理请求的线程就可以立即去处理其他请求,当数据库返回数据后,自动就发送给了调用者。
使响应式开发超越传统方式的关键因素是背压机制,就是数据流的生产端能够知道消费端的处理能力,并以此调整生产量。
这种感知能力非常重要,比如数据库操作的成本较高,那么在消费端真正准备好处理这些数据之后再进行数据库操作就很关键。
再比如消费端受限(如网络带宽不足),背压机制就可以确保生产端不会过度生产,就是说,当客户端不能很快的消费数据时,就会反向影响到响应式数据流,从而可以尽快通知数据库停止发送数据,数据库也就可以处理其他请求了,使系统的整体效率得到提升。
Spring 5 是基于 Reactor 项目实现的响应式开发,Reactor 中有两个核心类型 - Mono
他们都是数据流,Mono
流的处理是延迟的,生产者只有在收到消费者的指示时才会真正生产数据,是通过调用 subscribe() 来实现的,例如:
subscribe() 中传入的是一个消费者,会处理接收到的每条数据。
Java 9 中已经集成了reactive stream,思路和Reactor项目相同,如果想了解更多,可以看一下之前的文章 Java 9 新特性:Reactive Streams
可以看到,和我们之前的写法没有多少不同,还是使用熟悉的注解,只是返回类型不同了,使用了 Flux 和 Mono,用来返回响应式类型的数据,其他的工作都由框架来帮我们做。
我们再简单对比下传统方式和响应式的不同:
传统方式下,数据是全部从数据库读取出来之后才从server发送到client,图示:
响应模式下,只要有数据就绪了,就立即发送给client,像流一样,图示:
这样client就可以更快的展示首条数据,server也不需要存放全部数据,数据的处理和传输都是即时的。
操作数据库的代码也需要是响应式的,Spring Data 已经提供了支持,只是目前还不全面,例如 MongoDB没问题,但 JDBC 还不行,需要等待一段时间。
下面以 mongodb 为例,看看响应式的数据库操作代码什么样:
和我们平时的代码有两点不同,一是使用的接口从普通的 CrudRepository 变为 ReactiveCrudRepository,二是返回类型使用了 Flux,编码方式变动非常小。
Reactive Programming 是非常好的开发方法,可维护性和可扩展性都非常好,相对于阻塞式开发,相同资源下性能会得到明显提升。
翻译整理自:
https://stackify.com/reactive-spring-5/
之后会分享 Spring Boot 2.0 响应式开发的内容。
请兄弟们帮忙点击下面的广告,帮我获得一丢丢广告费,感谢
点击 “阅读原文” 查看文章列表