reactive 编程模型有哪些价值?它的原理是什么?如何正确使用?文本为大家详细讲解。
reactive 和 reactive programming
reactive 直接翻译的意思式反应式,反应性。咋一看,似乎不太好懂。
举个例子:在 excel 里,c 单元格上设置函数 sum(a b),当你改变单元格 a 或者单元格 b 的数值时,单元格 c 的值同时也会发生变化。这种行为就是 reactive。
在计算机编程领域,reactive 一般指的是 reactive programming。指的是一种面向数据流并传播事件的异步编程范式(asynchronous programming paradigm)。
先举个例子大家感受一下:
public static void main(string[] args) { fluxprocessor<integer, integer> publisher = unicastprocessor.create(); publisher.doonnext(event -> system.out.println(receive event: event)).subscribe(); publisher.onnext(1); // print \\\'receive event: 1\\\' publisher.onnext(2); // print \\\'receive event: 2\\\' } 代码 1
以上例代码(使用 reactor 类库)为例,publisher 产生了数据流 (1,2),并且传播给了 onnext 事件, 上例中 lambda 响应了该事件,输出了相应的信息。上例代码中生成数据流和注册/执行 lambda 是在同一线程中,但也可以在不同线程中。
注:如果上述代码执行逻辑有些疑惑,可以暂时将 lambda 理解成 callback 就可以了。
reactive manifesto
对于 reactive 现在你应该大致有一点感觉了,但是 reactive 有什么价值,有哪些设计原则,估计你还是有些模糊。这就是 reactive manifesto 要解决的疑问了。
使用 reactive 方式构建的系统具有以下特征:
即时响应性 (responsive)
只要有可能, 系统就会及时地做出响应。即时响应是可用性和实用性的基石, 而更加重要的是,即时响应意味着可以快速地检测到问题并且有效地对其进行处理。即时响应的系统专注于提供快速而一致的响应时间, 确立可靠的反馈上限, 以提供一致的服务质量。这种一致的行为转而将简化错误处理、 建立最终用户的信任并促使用户与系统作进一步的互动。
回弹性 (resilient)
系统在出现失败时依然保持即时响应性。这不仅适用于高可用的、 任务关键型系统——任何不具备回弹性的系统都将会在发生失败之后丢失即时响应性。回弹性是通过复制、 遏制、 隔离以及委托来实现的。失败的扩散被遏制在了每个组件内部, 与其他组件相互隔离, 从而确保系统某部分的失败不会危及整个系统,并能独立恢复。每个组件的恢复都被委托给了另一个(外部的)组件, 此外,在必要时可以通过复制来保证高可用性。(因此)组件的客户端不再承担组件失败的处理。
弹性 (elastic)
系统在不断变化的工作负载之下依然保持即时响应性。反应式系统可以对输入(负载)的速率变化做出反应,比如通过增加或者减少被分配用于服务这些输入(负载)的资源。这意味着设计上并没有争用点和中央瓶颈, 得以进行组件的分片或者复制, 并在它们之间分布输入(负载)。通过提供相关的实时性能指标, 反应式系统能支持预测式以及反应式的伸缩算法。这些系统可以在常规的硬件以及软件平台上实现成本高效的弹性。
消息驱动 (message driven)
反应式系统依赖异步的消息传递,从而确保了松耦合、隔离、位置透明的组件之间有着明确边界。这一边界还提供了将失败作为消息委托出去的手段。使用显式的消息传递,可以通过在系统中塑造并监视消息流队列, 并在必要时应用回压, 从而实现负载管理、 弹性以及流量控制。使用位置透明的消息传递作为通信的手段, 使得跨集群或者在单个主机中使用相同的结构成分和语义来管理失败成为了可能。非阻塞的通信使得接收者可以只在活动时才消耗资源, 从而减少系统开销。
注:
上面描述有很多专有名词,可能有些疑惑,可以看下相关名词解释。
为什么使用 reactive 方式构建的系统会具有以上价值, 我稍后在 reactor 章节中介绍。
reactive stream
知道了 reactive 的概念,特征和价值后,是否有相关的产品或者框架来帮助我们构建 reactive 式系统呢?在早些时候有一些类库 (rxjava 1.x, rx.net) 可以使用,但是规范并不统一,所以后来 netfilx, pivotal 等公司就制定了一套规范指导大家便于实现它(该规范也是受到早期产品的启发),这就是 reactive stream 的作用。
reactive stream 是一个使用非阻塞 back pressure(回压)实现异步流式数据处理的标准。目前已经在 jvm 和 javascript 语言中实现同一套语意的规范;以及尝试在各种涉及到序列化和反序列化的传输协议(tcp, udp, http and websockets)基础上,定义传输 reactive 数据流的网络协议。
the purpose of reactive streams is to provide a standard for asynchronous stream processing with non-blocking backpressure.
reactive streams 解决的问题场景
当遇到未预料数据流时,依然可以在可控资源消耗下保持系统的可用性。
reactive streams 的目标
控制在一个异步边界的流式数据交换。例如传递一个数据到另外一个线程或者线程池,确保接收方没有 buffer(缓存)任意数量的数据。而 back pressure(回压)是解决这种场景的不可或缺的特性。
reactive streams 规范适用范围
此标准只描述通过回压来实现异步流式数据交换的必要的行为和实体,最小接口,例如下方的 publisher, subscriber。reactive streams 只关注在这些组件之间的流式数据中转,并不关注流式数据本身的组装,分割,转换等行为, 例如 map, zip 等 operator。reactive streams 规范包括:
publisher
产生一个数据流(可能包含无限数据), subscriber 们可以根据它们的需要消费这些数据。
public interface publisher<t> { public void subscribe(subscriber<? super t> s);} subscriber
publisher 创建的元素的接收者。监听指定的事件,例如 onnext, oncomplete, onerror 等。
publicinterface subscriber<t> { public void onsubscribe(subscription s); public void onnext(t t); public void onerror(throwable t); public void oncomplete();} subscription
是 publisher 和 subscriber 一对一的协调对象。subscriber 可以通过它来向 publisher 取消数据发送或者 request
Forrester:阿里云跻身全球SaaS云市场TOP3.net.cn域名后缀特点Q&A解答阿里云轻量级服务器刷镜像版本域名每年续费多少钱企业免费网站注册有什么优势?合肥手机网站建设的特点都有哪些?edu域名查询方法有哪些?edu域名有哪些注册条件?申请的域名如何使用?申请域名之后要注意什么?