Reactive响应式/反应式编程

  Reactive响应式(反应式)编程 是一种新的编程风格,其特点是异步或并发、事件驱动、推送PUSH机制以及观察者模式的衍生。reactive应用(响应式应用)允许开发人员构建事件驱动(event-driven),可扩展性,弹性的反应系统:提供高度敏感的实时的用户体验感觉,可伸缩性和弹性的应用程序栈的支持,随时可以部署在多核和云计算架构。

  Merriam-Webster 定义reactive是“随时响应刺激”的响应,也就是说,它的组件是“活跃”,随时准备接收事件。这个定义抓住了reactive本质。

聚焦在系统上有如下定义:

  1. react to events 对事件立即反应
    事件驱动的自然特性使的反应能够立即加载实施,通过避免对共享资源的争用实现可扩展性。
  2. react to failure 对失败立即反应
    在任何级别都可以建立一个能够实现失败恢复的弹性系统。
  3. react to users 对用户立即反应
    无论任何负载,值得荣耀的响应时间。

 

事件驱动:Event-driven

  基于异步通信的应用程序实现了松耦合的设计,好过于纯粹基于同步的方法调用。发送方和接受方可以实现调用,不要关心事件是如何传播的细节,通过接口实现通信。这就易于延伸,发展和维护,带来更多的灵活性,并降低了维护成本。

  由于异步通信的接受人可以在事件发生时或收到一条消息之前保持休眠状态,事件驱动event-driven的方法可以有效地利用现有资源,让多个收件人可以共享一个硬件线程。相比基于同步的传统应用程序,一个非阻塞的应用程序在重负载下可以拥有更低的延迟和更高的吞吐量,这将导致更低的运营成本,提高了资源利用率以及良好的终端用户体验。

  在一个事件驱动的应用程序中,组件彼此交互是通过离散事件的生产者和消费者( production/consumption )。这些事件是以异步和非阻塞的方式发送和接收的。事件驱动的系统往往依靠推而不是拉或投票表决,即他们是在有消息时才推送数据给消费者,而不是通过一种浪费资源方式:让消费者不断地轮询或等待数据。

  异步发送事件:也被称为消息传递意味着应用程序设计于高并发,能够无需改动利用多核硬件。任何一个CPU内核都是能够处理任何消息事件,这导致并行的机会急剧增加。

  非阻塞:意味着应用程序在故障等突发情况下任何时候都能实现响应。而对于这一切所需的资源响应,例如CPU,内存和网络都不会发生垄断。因此,它可以同时兼具更低的延迟,更高的吞吐量和更好的可扩展性。

  传统的服务器端架构是依赖于在一个单独的线程中共享可变状态和实现阻塞操作。这样的系统在满足不断变化的需求时难以扩展伸缩,共享可变状态需要同步,它引入了附带的复杂性和不确定性,使得程序代码很难理解和维护。把一个线程通过阻断方式使用实际是限制了资源,并带来高昂的唤醒成本。

  事件的产生和处理的解耦,能够让运行平台更关注同步细节以及事件是如何跨线程分发的,当程序抽象抬升到业务流程级别,你考虑的是事件如何传播以及如何通过系统组件之间进行交互,而不是摆弄周围的低级初始设备如线程和锁。

  事件驱动的系统使组件和子系统之间的松耦合。这是可扩展性和弹性的先决条件之一。通过消除复杂和强大的组件之间的依赖,事件驱动的应用可以通过影响最小的方式扩展现有的应用程序。

 

Resilient弹性

  弹性有以下含义:

  1. 物质或物体拥有形状上弹回的能力。
  2. 从困难中恢复的能力。

  在一个reactive应用中,应变能力不是一个可有可无的东西,而是从一开始就成为设计的一部分。故障应对在编程模型中构建时就第一面对,这就导致应用程序是高度宽容失败并在运行时能够提供手段愈合修复自己。传统的故障处理是不能做到这一点,因为它是要么防御小,要么过于激进,你必须在系统的一个个地方去处理异常Exception(banq:将你的方法到处加上try{}catch)。

  为了管理失败,我们需要一种方法来隔离它,使它不会扩散到其他健康的部位,并能观察它,从失败的上下文以外的安全点对其进行管理。如果其中一个出现故障,不影响其他的。这可以防止级联故障的经典的问题,并允许隔离管理问题。

  事件驱动的松散耦合提供了组件在失败下可以抓获完全隔离的上下文场景,作为消息封装,发送到其他组件时,在具体编程时可以检查错误比如是否接受到,接受的命令是否可执行等等,并决定如何应对。

  这种方法创建了一个能让业务逻辑保持清洁的系统,显式的隔离分开处理Exception的有利于观察,管理和配置,并能让系统自行愈合,并自动恢复。这类似在一个大公司内,将一个问题逐步向上升级,直到达到有权力来处理它的水平。

  这个模型的美妙之处在于它是纯粹的事件驱动,它是reactive组件和异步事件,意味着在分布式环境中具有在本地一台服务器范围内相同的语义。

Responsive实时响应

  这是迅速回应或作出适当的反应的意思, 我们使用这个词在一般意义上不应该与响应的网页设计混淆,后者主要是指CSS媒体查询和渐进增强。

  响应的应用程序是实时的,耐看的,丰富的和协作。企业与他们的客户建立一个开放的和持续的对话,欢迎他们通过响应的互动体验。这使得它们更有效率,建立连接,并配备解决问题和完成任务的感觉。一个例子是,在使用谷歌Docs 时,几个用户能够编辑文档协作,能实时地让他们看到彼此的编辑和注释的结果。

  对事件作出响应的应用程序,需要及时去做(just do it),即使存在故障情况。如果应用程序在长时间不做出回应,称为延迟,这个系统实际是不可用的,因此不能被视为弹性。

  当然并非所有应用如武器或医疗监控系统这样对实时要求如此高,但是通常他们在运行一段时间后出现迅速下降的性能,才可以从他们偏离了一点响应限制看出(banq: windows越用越慢),假如是金融交易应用程序可能会失去目前的交易没有及时回应。

后压(back pressure)

  Reactive流的主要特征是“back pressure后压”:也就是说,系统会在它的请求buffer被充满时,将其推送会给发送者,让发送者稍后再试,或者使用其他接收器,这就能确保发送者和接收者之间的管道不会被充满,这样才有机会获得一个响应式系统。

  这里有一个源码展示使用 Akka Streams, Ratpack, Reactor 和 RxJava在一个流Stream中相互协作的代码案例.

reactivemanifesto.org

go reactive宣言

何为reactive applications

Reactive设计语言与范式

 

JVM应用

RxJava教程

AKKA框架

Actors模型

vertx入门教程

异步编程

Ratpack可快速开发异步响应式的Java Web应用 

基于Vert.x和SpringBoot实现响应式开发

Lagom是一个集成ES/CQRS的Reactive微服务框架

使用Spring Cloud和Reactor在微服务中实现EventSourcing

如何理解Stream processing, Event sourcing, Reactive, CEP?

使用Vert.x开发响应式微服务

Spring 5与Spring cloud的响应式编程之旅

Spring Cloud Stream的函数式和响应式Reactive编程特点

更多#Reactive编程专题

 

Javascript

前端Flux架构简介

什么是Redux?

React.JS基础教程

React.js

使用Angular2建立一个可扩展单页应用

React/Redux有关资源和文章

 

Reactive编程专题

并发编程

异步编程

Actor模型

性能专题

扩展性设计

事务串行专题