美文网首页
响应式编程的基本概念

响应式编程的基本概念

作者: rickytang0 | 来源:发表于2017-08-18 16:08 被阅读0次

    什么是相应式编程。简单的来说就是基于事件流的编程方式。

    什么是事件流,事件流就是将要发生事件按照时间顺序排序发生形成的。

    举个例子,比如我去星巴克点咖啡(注意我这里只强调我干了什么,这样表述会比较容易理解),我点了杯咖啡,我支付了现金,我等待咖啡煮好,我拿到了咖啡,我喝咖啡,我离开星巴克,结束所有流;又或者我拿咖啡的时候出现错误,发现咖啡不是我的,这样就会出错了,这样又结束了所有的流。可以参考下图,圆点代表每个事件,红色叉代表错误,黑色竖条代表结束。

    从例子和图中你可以看到组成响应式编程的三种动作(数据):事件(数据),错误,结束。通过得到这三个响应式动作,我们就可以在程序中作出不同的相应,使得我们编写的代码更加高效,简洁。

    响应式编程构建基础

    发布者(事件发送方,可以向它订阅)

    订阅者(事件订阅方)

    订阅(将发布者和订阅者联系起来,使订阅者可以向发布者发送数据)

    下面举了个例子将使用观察者模式来编写一个简单的功能。页面上有一个按钮和一个Label;当点击按钮,Label就会自动加1。HelloButtonController是监听者,HelloVM是发布者。HelloButtonController使用initCountOberver注册对HelloVM的监听。HelloButtonController在onClickedBtnCallback接收到按钮事件后,就调用HelloVM的addCount方法,HelloVM在更新了count的值后再掉用subjustCount通知HelloButtonController,让它刷新Label的显示。

    相应式编程的开发库

    要实现响应式编程,就有需要有适合这种工具,市面上主流的开源库RX系列,React,Agera等。

    这里我们着重介绍RX库,它有什么特点呢?

    1、只提供响应式编程的订阅功能;

    2、提供丰富的处理响应式流的API;

    3、支持多种语言平台(java,c++,js,lua等)

    使用rx的写上面的例子的代码:

    使用KVO的实现同样的例子

    如此看来,代码变得更加简洁更加高效。

    响应式编程的特点:

    事件驱动:Event-driven

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

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

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

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

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

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

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

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

    Resilient弹性

    弹性有以下含义:

    物质或物体拥有形状上弹回的能力。

    从困难中恢复的能力。

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

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

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

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

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

    Responsive实时响应

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

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

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

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

    后压(back pressure)

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

    相关文章

      网友评论

          本文标题:响应式编程的基本概念

          本文链接:https://www.haomeiwen.com/subject/bbearxtx.html