二:反应式编程

5、rxjava
6、reactor
7、webflux(异步servlet/netty)
8、Hystrix

反应式编程引入

函数响应式编程是一个来自90年代后期受微软的一名计算机科学家Erik Meijer启发的思想,用来设计和开发微软的Rx库。
Netflix在2012年开始意识到他们的架构要满足他们庞大的用户群体已经变得步履维艰。为了实现这一目标,他们决定尝试响应式,开始将.NET Rx迁移到JVM上面。他们不想只基于Java语言;而是整个JVM,从而有可能为市场上的每一种基于JVM的语言:如Java、Closure、Groovy、Scala等等提供一种新的工具。

反应式编程最早由 .NET 平台上的 Reactive Extensions (Rx) 库来实现。后来迁移到 Java 平台之后就产生了著名的 RxJava 库,并产生了很多其他编程语言上的对应实现。在这些实现的基础上产生了后来的反应式流(Reactive Streams)规范。该规范定义了反应式流的相关接口,并集成到 Java 9 中。

Rx vs Callback vs Future

对于简单的单任务异步问题,future似乎很满足。但如果一个任务有很多个并行的子任务,这些子任务又相互依赖,future实现起来就力不从心了,这会使得future程序写得异常复杂。

Callback呢?它和future的不同之处在于它的非阻塞性,future.get()是阻塞的,而callback则不会阻塞任何东西,因此从技术上来将callback的效率是优于future的,但它同样没有解决复杂的,相互依赖的子任务带来的复杂性,回调很难组合起来,因为很快就会导致代码难以理解和维护(即所谓的“回调地狱(callback hell)”)。

反应式编程概念

背压

反应式流中第一个重要概念是负压(backpressure)。在基本的消息推送模式中,当消息发布者产生数据的速度过快时,会使得消息订阅者的处理速度无法跟上产生的速度,从而给订阅者造成很大的压力。当压力过大时,有可能造成订阅者本身的奔溃,所产生的级联效应甚至可能造成整个系统的瘫痪。

负压的作用在于提供一种从订阅者到生产者的反馈渠道。订阅者可以通过 request()方法来声明其一次所能处理的消息数量,而生产者就只会产生相应数量的消息,直到下一次 request()方法调用。这实际上变成了推拉结合的模式。

热(Hot) vs 冷(Cold)

在 Rx 家族的响应式库中,响应式流分为“热”和“冷”两种类型,区别主要在于响应式流如何 对订阅者进行响应:

一个“冷”的序列,指对于每一个 Subscriber,都会收到从头开始所有的数据。如果源头 生成了一个 HTTP 请求,对于每一个订阅都会创建一个新的 HTTP 请求。

一个“热”的序列,指对于一个 Subscriber,只能获取从它开始 订阅 之后 发出的数据。不过注意,有些“热”的响应式流可以缓存部分或全部历史数据。 通常意义上来说,一个“热”的响应式流,甚至在即使没有订阅者接收数据的情况下,也可以 发出数据(这一点同 “Subscribe() 之前什么都不会发生”的规则有冲突)。

你可能感兴趣的:(二:反应式编程)