反应式编程响应式reactive基本概念

反应式编程 (reactive programming) 是一种基于数据流 (data stream) 和 变化传递 (propagation of change) 的声明式 (declarative) 的编程范式。

反应式编程是在命令式编程、面向对象编程之后出现的一种新的编程模型,是一种以更优雅的方式,通过异步和数据流来构建事务关系的编程模型。本文包括反应式编程的概述和 RxPy 实战,以及怎样去理解反应式编程才能更好的把它融入到我们的编程工作中,把反应式编程变成我们手中的利器。

使用异步数据流进行编程,这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。反应式编程提高了代码的抽象级别,可以只关注定义了业务逻辑的那些相互依赖的事件。

反应式系统具有如图所示的4个特性:

  1. 即时响应性,对用户有反应: 对用户有反应我们才说响应,一般我们说的响应,基本上都说得针对跟用户来交互。只要有可能,系统就会及时响应。

  2. 回弹性,对失败有反应: 应用失败了系统不能无动于衷,不能等着它挂掉,要有反应,使其具备可恢复性。可恢复性可以通过复制、监控、隔离和委派等方式实现。在可恢复性的系统中,故障被包含在每个组件中,各组件之间相互隔离,从而允许系统的某些部分出故障并且在不连累整个系统的前提下进行恢复。当某个模块出现问题时,需要将这个问题控制在一定范围内,这便需要使用隔绝的技术,避免雪崩等类似问题的发生。或是将出现故障部分的任务委托给其他模块。回弹性主要是系统对错误的容忍。

  3. 弹性,对容量和压力变化有反应: 在不同的工作负载下,系统保持响应。系统可以根据输入的工作负载,动态地增加或减少系统使用的资源。这意味着系统在设计上可以通过分片、复制等途径来动态申请系统资源并进行负载均衡,从而去中心化,避免节点瓶颈。如果没有状态的话,就进行水平扩展,如果存在状态,就使用分片技术,将数据分至不同的机器上。

     

  4. 消息驱动,对输入有反应: 响应系统的输入,也可以叫做消息驱动。反应式系统依赖异步消息传递机制,从而在组件之间建立边界,这些边界可以保证组件之间的松耦合、隔离性、位置透明性,还提供了以消息的形式把故障委派出去的手段。

     

前三种特性(即时响应性, 回弹性, 弹性)更多的是跟你的架构选型有关,我们可以很容易理解像 Microservices、Docker 和 K8s 这样的技术对建立反应式系统的重要性。

回压(Backpressure)

这里要特别要提一下回压(Backpressure), Backpressure 其实是一种现象,在数据流从上游生产者向下游消费者传输的过程中,上游生产速度大于下游消费速度,导致下游的 Buffer 溢出,这种现象就叫做 Backpressure 出现。这句话的重点不在于”上游生产速度大于下游消费速度”,而在于”Buffer 溢出”。回压和 Buffer 是一对相生共存的概念,只有设置了 Buffer,才有回压出现;只要设置了 Buffer,一定存在出现回压的风险。

比如我们开发一个后端服务,有一个 Socket 不断地接收来自用户的请求来把用户需要的数据返回给用户。我们服务所能承受的同时访问用户数是有上限的,假设最多只能承受 10000 的并发,再多的话服务器就有当掉的风险了。对于超过 10000 的用户,程序会直接丢弃。那么对于这个案例 10000 就是我们设置的 Buffer,当超过 10000 的请求产生时,就造成了回压的产生;而我们程序的丢弃行为,就是对于回压的处理。

对于回压我们一般有两种处理方式,一种就是上面举例中的拒绝或丢弃,这是否定应答的方式,另一种是肯定应答,先收下来,然后再慢慢处理。

 

 

 

Rx

反应式编程最着名的实现是 ReactiveX,其为 Reactive Extensions 的缩写,一般简写为 Rx ,发展历程如图所示:

640?wx_fmt=png

微软 2009 年 以 .Net 的一个响应式扩展的方式创造了Rx,其借助可观测的序列提供一种简单的方式来创建异步的,基于事件驱动的程序。2012 年 Netflix 为了应对不断增长的业务需求开始将 .NET Rx 迁移到 JVM 上面。并于 2013 年 2 月份正式向外发布了 RxJava 。

Rx的组成包括5部分,被观察者或者叫发射源,观察者/订阅者或者叫接收源,订阅,调度器,操作符。

  • Observable<Data> 被观察者可以被观察者订阅,被观察者将数据push给所有的订阅者

  • Subscriber /Observer

  • Subscription 订阅可以被取消订阅

  • Schedulers 调度器是Rx的线程池,操作中执行的任务可以指定线程池,我们可以通过subscribeOn来指定Observable的任务在某线程池中执行Observable

  • 也可以通过observeOn来指定订阅者/观察者们,在哪个线程执行onNext, onComplete, onError
    Operators 操作符可以对数据流进行各种操作,包括创建,转换,过滤,组装,合并 ,筛选等等

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章