[译]响应式编程笔记一:响应式总览

# Notes on Reactive Programming Part I: The Reactive Landscape

响应式编程笔记一:响应式总览


>响应式编程 经常和并发编程还有高性能等一起出现,所以很难区分这些概念,但是,本质上他们是完全不同的东西。困惑了吧。


响应式编程 通常是指函数式响应式编程(FRP)。

有些人认为响应式不是什么新鲜东西,而是他们整天接触的东西(多数应该是JavaScript用户)。

另外一些则认为这是Microsoft带来的东西。

而在企业Java开发领域,最近才有一些声音(见[Reactive Streams initiative](http://www.reactive-streams.org/)),如同任何新鲜事物一样,关于什么时候用以及用在哪里的问题,总有很多显而易见的错误。


## 是什么

响应式编程 是micro-architecture的一种风格,涉及了智能路由和事件消费。嗯,略抽象。


响应式编程 源自1970s,老生常谈了,然而却与现代企业的某些东西共鸣。

这个共鸣的时间,就是microservices还有多核处理器流行的时间。


>响应式编程 背后的基本理念是 有特定的数据类型能够代表以后的值 (a value over thime)。涉及到这些随时间改变的值的计算,本身还会随时间而改变。 (Computations that involve these changing-over-time values will themselves have values that change over time.)

>一个简单的例子是,将你的程序想象成一个spreadsheet,所有的变量都是cells。如果任何cell发生了变化,相关联的cells都会发生变化。这就和FRP很类似。

(from [Terminology Question on Stackoverflow](https://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming))


FRP 与高性能、并发、异步操作、还有非阻塞IO 有着密切关系。


## 响应式用例

**External Service Calls (外部服务调用)** 很多后端服务都是RESTful(基于HTTP),所以其底层协议都是阻塞式和同步的。想象一下,一个服务调用了另一个服务,而这个返回值又被多个服务所依赖。这么多的IO,如果你还是等待一个调用完成,再发出下一个请求,你的客户也许会因此而放弃。所以,外部服务调用,特别是复杂依赖的调用,是一个需要优化的情况。FRP offers the promise of "composability" of the logic driving those operations, so that it is easier to write for the developer of the calling service.

**Highly Concurrent Message Consumers (高并发消息消费者)** 消息的处理,特别是高并发情况下的,是一个常见的用例。响应式框架 都喜欢测试,然后吹嘘JVM中每秒能处理多少消息。这些测试结果通常是难以置信的(轻松达到百万级别),但也可能是造假 - 有些仅仅是测试简单的for循环。然而,响应式模式天然适合消息处理(因为event可以等价于message)。

**Spreadsheets** 也许不是真正的企业用力,但各位可以轻松理解其理念。如果cell B依赖 cell A,而cell C同时依赖 cell A和cell B,那么,如何传播A的更改,从而确保C不会先于B接收到通知?这也是**FRP和简单的事件驱动编程的区别 - FRP会智能路由(intelligent routing)**。

**Abstraction Over (A)synchronous Processing** 略。

这篇博客有一些真实的用例:[Netflix Tech Blog: Functional Reactive in the Netflix API with RxJava](http://techblog.netflix.com/2013/02/rxjava-netflix-api.html)


## 对比

**Ruby Event-Machine** Event Machine 是并发编程(通常涉及非阻塞IO)的一个抽象。略。

**Actor Model** 同样可以追溯到1970s。Actors一种计算抽象(与数据和行为相对),允许并发作为一个天然的consequence,这样,他们可以形成一个并发系统的基础。Actors彼此发送消息,所以某种意义上就是响应式的,有很多重叠的概念。二者的区别通常是在他们的实现层上,如Akka中的Actors可以被分布到进程中。

**Deferred result (Futures)** Java 1.5 引入了"java.util.concurrent",其中就有deferred result的概念,封装在Future中。当你仅需要并发处理一组相似的任务时,Futures很棒,但是如果任何一个任务想要依赖于其他任务或者有条件的执行时,你会掉进某种"nested callback hell"。响应式编程提供了一种解决方案。

**Map-reduce and fork-join** 并行处理的抽象,很有用,也有很多可以选择的例子。MapReduce和Hadoop,以及JDK 1.7中的Fork-Join。这些很有用的抽象,但相较于FRP来说,有点肤浅了。前者仅是简单并行处理的抽象,后者更进一步,可组装、声明式通信。

**Coroutines** coroutine是subroutine的泛化 - it has an entry point, and exit point(s) like a subroutine,但是,当其退出时,它会将控制传递给其他的coroutine(没有必要传给它的调用者),其累积的任何状态,都会被保存,并记住,用于下次被调用。coroutines可被用作更高级别功能(如Actors和Streams)的building block。响应式编程的目标之一,就是为通信中的并行处理agents提供同样类型的抽象,因此,coroutines(如果它们可用的话)是一个很有用的building block。There are various flavours of coroutines, some of which are more restrictive than the general case, but more flexible than vanilla subroutines. Fibers (see the discussion on Event Machine) are one flavour, and _Generators (familiar in Scala and Python) are another_.


## Java中的响应式编程

Java不是一个响应式语言,因为它自己是不支持coroutines的。

JVM上的其他语言如Scala和Clojure,则更原生地支持响应式模型,Java则直到9才开始。

但是,Java有很多基于JDK提供的响应式layers。来看一下。


**Reactive Streams** 是一个非常低级别的约定,提供了一些Java接口(以及一个TCK),但同样适用于其他语言。

这些接口,描述了Publisher和Subscriber的基本building blocks,有显式的back pressure,形成了可共同操作的库的通用语言。Reactive Streams已经被纳入了JDK 9,就是java.util.concurrent.Flow。

**RxJava** Netflix/RxJava,后续又改成了ReactiveX/RxJava。

Netflix does a lot of programming in Groovy on top of RxJava, but it is open to Java usage and quite well suited to Java 8 through the use of Lambdas.

There is a [bridge to Reactive Streams](https://github.com/ReactiveX/RxJavaReactiveStreams).

RxJava 是第二代库,根据 David Karnok’s [Generations of Reactive](https://akarnokd.blogspot.co.uk/2016/03/operator-fusion-part-1.html) 的分类.

**Reactor** 是一个Java框架,由Pivotal开源团队提供(还提供Spring)。直接基于Reactive Streams,所以不需要bridge。Reactor IO proj 提供了对低级别网络运行时的封装,如Netty和Aeron。被称为第四代库。

**Spring Framework 5.0** 已经内含了响应式特性,包括构建HTTP服务器和客户端的工具。使用Spring进行web开发的用户,会发现处理响应式请求分派和背压的多数情况非常熟悉。Spring基于Reactor,但还提供了API,允许选择其他的库,如RxJava。用户可以选择Tomcat、Jetty、Netty(via Reactor IO) 以及Undertow作为服务侧网络栈。

**Ratpack** 基于HTTP构建高性能服务的一组库。基于Netty,实现了Reactive Stream。

**Akka** 一个工具套件,用于使用Scala或Java构建Actor模式的应用,使用Akka Streams进行进程内通信,内建Reactive Streams contracts。是第三代库。


## 为什么现在?

The driver is efficient resource utilization, or in other words, spending less money on servers and data centres. The promise of Reactive is that you can do more with less, specifically you can process higher loads with fewer threads. This is where the intersection of Reactive and non-blocking, asynchronous I/O comes to the foreground. For the right problem, the effects are dramatic. For the wrong problem, the effects might go into reverse (you actually make things worse).

就是需要有效利用资源。

记住,这只是个工具,具体还是看你怎么用。


## 来源

https://spring.io/blog/2016/06/07/notes-on-reactive-programming-part-i-the-reactive-landscape#reactive-use-cases

原文地址:https://www.cnblogs.com/larryzeal/p/8496869.html