精华内容
下载资源
问答
  • 本篇文章主要介绍了浅谈Spring5 响应式编程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • SpringBoot2.0不容错过的新特性 WebFlux响应式编程
  • Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务...使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架
  • Rxjava 响应式编程

    2018-07-19 17:24:36
    响应式编程是一种基于异步数据流概念的编程模式。数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一条流合并为一条新的流。 响应式编程的一个关键概念是事件。事件可以被等待,可以触发...
  • 响应式编程

    千次阅读 2019-05-07 15:26:39
    我们先来聊一聊响应式的由来,对于它的由来,我们可能需要先从一段常见的代码片段看起 int a=1; int b=a+1; System.out.print(“b=”+b) // b=2 a=10; System.out.print(“b=”+b) // b=2 上面是一段很...

    维护关系,却不执行,然后根据触发后再去执行。 相当于原编程运行思路的逆向。

     

    响应式的由来

    我们先来聊一聊响应式的由来,对于它的由来,我们可能需要先从一段常见的代码片段看起

    int a=1;
    int b=a+1;
    System.out.print(“b=”+b)    //  b=2
    a=10;
    System.out.print(“b=”+b)    //  b=2
    
    

    上面是一段很常见的代码,简单的赋值打印语句,但是这种代码有一个缺陷,那就是如果我们想表达的并不是一个赋值动作,而是b和a之间的关系,即无论a如何变化,b永远比a大1。那么可以想见,我们就需要花额外的精力去构建和维护一个b和a的关系。

    而响应式编程的想法正是企图用某种操作符帮助你构建这种关系。
    它的思想完全可以用下面的代码片段来表达:

     
    int a=1;
    int b <= a+1;   // <= 符号只是表示a和b之间关系的操作符
    System.out.print(“b=”+b)    //  b=2
    a=10;
    System.out.print(“b=”+b)    //  b=11
    
    

    这就是是响应式的思想,它希望有某种方式能够构建关系,而不是执行某种赋值命令。

    至此你可能不禁要问,我们为什么需要构建关系的代码而不是命令式的代码呢?如果你翻一翻自己正在开发的APP,你就能看到的每一个交互的页面其实内部都包含了一系列的业务逻辑。而产品的每个需求,其实也对应了一系列的业务逻辑相互作用。总之,我们的开发就是在构建一系列的业务逻辑之间的关系。你说我们是不是需要构建关系的代码?

    说回响应式,前期由于真实的编程环境中并没有构建关系的操作符,主流的编程语言并不支持这种构建关系的方式,所以一开始响应式主要停留在想的层面,直到出现了Rx和一些其他支持这种思想的框架,才真正把响应式编程引入到了实际的代码开发中。

    Rx是响应式拓展,即支持响应式编程的一种拓展,为响应式在不同语言中的实现提供指导思想

    什么是响应式编程

    说完了了响应式的由来,我们就可以谈谈什么是响应式编程了。

    响应式编程是一种通过异步和数据流来构建事务关系的编程模型。这里每个词都很重要,“事务的关系”是响应式编程的核心理念,“数据流”和“异步”是实现这个核心理念的关键。为了帮助大家理解这个概念,我们不妨以APP初始化业务为例来拆解一下这几个词。

     

    这是一个比较理想化的APP初始化逻辑,完成SDK初始化,数据库初始化,登陆,之后跳转主界面

    事务的关系

    • 事务

      • 是一个十分宽泛的概念,它可以是一个变量,一个对象,一段代码,一段业务逻辑.....但实际上我们往往把事务理解成一段业务逻辑(下文你均可以将事务替换为业务逻辑来理解),比如上图中,事务就是指APP初始化中的四个业务逻辑。
    • 事务的关系

      • 这种关系不是类的依赖关系,而是业务之间实际的关系。比如APP初始化中,SDK初始化,数据库初始化,登陆接口,他们共同被跳转页面业务所依赖。但是他们三个本身并没有关联。这也只是业务之间较为简单的关系,实际上,根据我们的需求App端会产生出许多业务之间错综复杂的关系。

    数据流

    关于Rx的数据流有很多说法,比如“Everything is a stream”,“Thinking with stream”等等。虽然我明白这只是想强调流的重要性,可是这些话折射出来的编程思路其实是很虚无缥缈的,只会让开发者对于Rx编程更加迷惑。

    实际上,数据流只是事务之间沟通的桥梁。

    比如在APP初始化中,SDK初始化,数据库初始化,登陆接口这些业务完成之后才会去安排页面跳转的操作,那么这些上游的业务在自己工作完成之后,就需要通知下游,通知下游的方式有很多种,其中最棒的的方式就是通过数据(事件)流。每一个业务完成后,都会有一条数据(一个事件)流向下游,下游的业务收到这条数据(这个事件),才会开始自己的工作。

    但是,只有数据流是不能完全正确的构建出事务之间的关系的。我们依然需要异步编程。

    异步

    异步编程本身是有很多优点的,比如挖掘多核心CPU的能力,提高效率,降低延迟和阻塞等等。但实际上,异步编程也给我们构建事务的关系提供了帮助。

    在APP初始化中,我们能发现SDK初始化,数据库初始化,登陆接口这三个业务本身相互独立,应当在不同的线程环境中执行,以保证他们不会相互阻塞。而假如没有异步编程,我们可能只能在一个线程中顺序调用这三个相对耗时较多的业务,最终再去做页面跳转,这样做不仅没有忠实反映业务本来的关系,而且会让你的程序“反应”更慢

    小结

    总的来说,异步和数据流都是为了正确的构建事务的关系而存在的。只不过,异步是为了区分出无关的事务,而数据流(事件流)是为了联系起有关的事务

    APP初始化应该怎么写

    许多使用Rx编程的同学可能会使用这种方式来完成APP的初始化。

    Observable.just(context)
                .map((context)->{login(getUserId(context))})
                .map((context)->{initSDK(context)})
                .map((context)->{initDatabase(context)})
                .subscribeOn(Schedulers.newThread())
                .subscribe((context)->{startActivity()})
    

    其实,这种写法并不是响应式的,本质上还是创建一个子线程,然后顺序调用代码最后跳转页面。这种代码依然没有忠实反映业务之间的关系。

    在我心目中,响应式的代码应该是这样的

    
    Observable obserInitSDK=Observable.create((context)->{initSDK(context)}).subscribeOn(Schedulers.newThread())
    
    Observable obserInitDB=Observable.create((context)->{initDatabase(context)}).subscribeOn(Schedulers.newThread())
    
    Observable obserLogin=Observable.create((context)->{login(getUserId(context))})
                                  .map((isLogin)->{returnContext()})
                                .subscribeOn(Schedulers.newThread())
                                
    Observable observable = Observable.merge(obserInitSDK,obserInitDB,obserLogin)
    
    observable.subscribe(()->{startActivity()})
    
    

    大家应该能很明显看到两段代码的区别,第二段代码完全遵照了业务之间客观存在的关系,可以说代码和业务关系是完全对应的。

    那么这带来了什么好处呢?当initSDK,initDB,Login都是耗时较长的操作时,遵照业务关系编写响应式代码可以极大的提高程序的执行效率,降低阻塞。

    理论上讲,遵照业务关系运行的代码在执行效率上是最优的。

    为什么引入响应式编程

    对响应式编程有了一些了解之后,我知道马上会由很多人跳出来说,不使用这些响应式编程我们还不是一样开发APP?

    在这里我希望你理解一点,当我们用老办法开发APP的时候,其实做了很多妥协,比如上面的APP初始化业务,三个无关耗时操作为了方便,我们往往就放在一个线程环境中去执行,从而牺牲了程序运行的效率。而且实际开发中,这种类似的业务逻辑还有很多,甚至更加复杂。假如不引入响应式的思路,不使用Rx的编程模型,我们面对这么些复杂的业务关系真的会很糟心。假如你做一些妥协,那就会牺牲程序的效率,假如你千辛万苦构建出业务关系,最终写出来的代码也一定很复杂难以维护。所以,响应式编程其实是一种更友好更高效的开发方式。

    根据个人经验来看,响应式编程至少有如下好处:

    • 在业务层面实现代码逻辑分离,方便后期维护和拓展
    • 极大提高程序响应速度,充分发掘CPU的能力
    • 帮助开发者提高代码的抽象能力和充分理解业务逻辑
    • Rx丰富的操作符会帮助我们极大的简化代码逻辑

    一个复杂一些的例子

    接下来,我就以我们团队目前的一款产品的页面为例,详细点介绍运用响应式编程的正确姿势。

    接下来,我就以我们团队目前的一款产品的页面为例,详细点介绍运用响应式编程的正确姿势。

    首先,UI和产品沟通后,可能会给我们这样的设计图(加上一些尺寸的标注)。但是我们并不需要急忙编码,我们首先要做的是区分其中相对独立的模块。

    上图我做了一点简单的标注。把这个页面的业务逻辑简单的分为四个相互独立的模块,分别是视频模块,在线人数模块,礼物模块,消息模块。他们相互独立,互不影响。接下来,我们再去分析每个模块内部的业务并构建起业务之间的关系。大致如下:

    构建了业务之间的关系图,其实我们的工作已经完成了一半了,接下来就是用代码实现这个关系图。在这里,我就以其中一小段业务关系来编写代码给大家示范。

        Observable obserDownload=Observable.just(url)
                                            .map((url)->{getZipFileFromRemote(url)});
        Observable obserLocal=Observable.just(url)
                                            .map((url)->{getZipFileFromLocal(url)});
        Observable obserGift=Observable.concat(obserLocal,obserDownload)
                                            .takeUnitl((file)->{file!=null});
        obserGift.subscribeOn(Schedulers.io()).flatMap((file)->{readBitmapsFromZipFile(file)})
                                            .subscribe((bitmap)->{showBitmap(bitmap)})
    
    
    

    以上是我手写的伪代码,可能细节上有些问题,但大体思路就是这样。

    有人可能会说,那是因为你运用操作符比较熟练才能这么写。其实操作符都是我查的,我记不住那么多操作符,所以基本上我都是先理清楚业务之间的关系,需要和并逻辑的时候,就去去查合并类的操作符,需要条件判断来分流的逻辑时去找条件判断类的操作符。基本上都能满足需求。你瞧,写代码就是这么简单,后续即使需要增加需求,代码修改起来也很清晰,因为无关的业务已经被你分离好了。



    转载自https://www.jianshu.com/p/c95e29854cb1

     

    展开全文
  • java响应式编程,red hat公司出品,要学习的走起哦 building reactive microservices in java
  • 活性弹簧 使用WebFlux / Reactor在Spring中进行响应式编程 :pushpin: 내용 :writing_hand:
  • SpringMVC是同步阻塞的IO模型,资源浪费相对来说比较严重,当我们在处理一个比较耗时的任务时,例如:上传一个比较大的文件,首先,服务器的线程一直在等待接收文件,在这期间它就像个傻子一样等在那儿(放学别走)...
  • 文档主要是在阅读完Java设计模式及实践之后对响应式编程与响应式设计模式的总结,对于加深自己的理解挺有益的。
  • spring 响应式编程的入门案例。使用了 全栈式响应式编程
  • 一文搞懂: 响应式编程是什么?

    千次阅读 2021-01-10 16:09:15
    当一个系统具有即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)。 我们称这样的系统为反应系统(Reactive System)。

    导言

    目前响应式编程还属于大乱斗的时代,各家有各家的定义和实现。响应式宣言定义了响应式应该满足的特性。Spring5有自己的响应式方案技术栈、广为人知的rxJava所属的reactiveX也有自己的理解。有的说响应式是基于事件的,有的说是基于数据流的。有人说响应式编程其实只是个便于并发编程的api库,有人说响应式编程是一种编程思想、一种编程范型。技术圈子里各有各的说法,正如小马哥所说: 一种技术,各自表述。响应式编程含糊不清、有些空洞无实、有些夸大其词,难免让普通学习者难以入门,十分头痛。
    在这里插入图片描述

    以下主要基于响应式宣言和reactiveX来解释响应式编程,所说观点如有异议欢迎评论区讨论指教。

    响应式编程是什么?

    是一款使用异步数据流编程的响应式编程思想。(from here)

    Reactive Programming是基于观察者模型的这是大家的共识,它提供了非阻塞、异步的特性,便于处理异步情景,从而避免回调地狱和突破Future的局限性: 难以组合。(这个优点我并不认同,java8 的completeFuture已经有很好的改善了)。

    在reactiveX中,对好几个语言提供了api库,该库扩展了观察者模式,支持基于数据事件的驱动。允许声明式组合观察者序列。将同步编程和异步编程抽象成统一。

    异步编程和同步编程在代码中的体现可以如下表体现。不同于传统的pull型的,响应式编程通常采用push型的数据传输,由生产者控制消费速度,但当消费者消费速度不足时,也能反过来提示生产者降低生产速度(backPressure),backPressure将在下文阐述。

    响应式编程通常带有函数式的思想,但这是用来简化面向对象语法臃肿性的,响应式编程的核心在于Reactive,只是带有了部分的Functional的特性,更不是Functional Reactive Programming,这是完全不同的东西。

    响应式宣言

    响应式系统应该具有什么特性

    当一个系统具有即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)。 我们称这样的系统为反应式系统(Reactive System)。

    img

    如图所示,响应式编程的价值在于1. 易于编写维护(特别是异步编程) 2. 及时响应。

    什么是及时响应? 不管是出了什么问题,或断电、或网络抖动、或代码bug,都能及时做出响应,提供足够的可用性。

    响应式宣言中将异常也看做一种消息来简化对错误的处理,其中错误可以简单看成看做各种Exception。

    什么是弹性? 回弹性?

    弹性是指不同负载下,系统的吞吐量、响应性没有什么区别。响应式通过伸缩算法,使系统没有资源争用点和中央瓶颈。

    回弹性是指当系统出现失败时,例如断电、硬件故障、资源耗尽等情况,通过复制、 遏制、 隔离以及委托来保证依然具有即时响应性。

    消息驱动还是事件驱动?

    消息时数据,事件是信号。消息的包含的信息量更丰富。

    对于消息驱动的系统,如果没有消息来,接受者异步非阻塞等待线程到来(休眠)。

    对于事件驱动的系统,常使用回调的方法实现。

    响应式宣言中推荐使用消息驱动来设计,因为事件驱动的系统很难实现回弹性:

    对于事件驱动系统,当处理过程已经就绪,监听器已经设置好, 以便于响应结果并对结果进行变换时, 这些监听器通常都将直接地处理成功或者失败, 并向原始的客户端报告执行结果。

    (这些监听器)响应组件的失败, 以便于恢复它(指失败的组件)的正常功能,而在另外一方面, 需要处理的是那些并没有与短暂的客户端请求捆绑在一起的, 但是影响了整个组件的健康状况的失败。

    响应式编程相关讨论

    为什么使用观察者模式

    使用该模式将开发者从回调地狱中解放出来。ReactiveX使用流来将异步、同步统一起来,并通过订阅者来将各种操作组合起来,提高了代码易读性。

    什么是回调地狱? 其实就是当回调函数需要组合时,常常会使代码复杂度大大增加,代码易读性大大减少的一种现象。

    ReactiveX的观察者模式是十分灵活的,不仅仅支持push、还支持pull。

    什么是背压(backPressure)

    其实背压翻译得不好,叫回压更合适。知乎上有个背压的解说我觉得说得特别好,背压其实只是一种现象,但响应式编程中的backPressure其实是一种解决消费赶不上生产时的一种处理策略,有让生产者慢点push的, 有直接丢弃的…

    在数据流从上游生产者向下游消费者传输的过程中,上游生产速度大于下游消费速度,导致下游的 Buffer 溢出,这种现象就叫做 Backpressure 。

    个人感想

    在我还是学生的时候就常听人说什么响应式编程、什么webflux,当时被各种新技术迷乱了眼睛的我胡乱的看了几个相关介绍,再听响应式编程被各种各样的博客文章吹嘘的多么多么好、多么多么先进,当时就觉得自己一定要学习。

    工作后才发现实际的生产其实不需要多么牛逼先进的东西,大多时候线上系统稳定性才是最重要的。国内java8还是大行其道,好多人java8的特性还没摸透,但依然在工作岗位上支撑起了一片天。

    对于开发者,不要被互联网上各式各样的“技术营销”骗了,在学习新技术前多想想是不是真的要学。什么代码、什么技术、什么框架,都只是互联网农民工手里的锤子罢了,不是越新越花哨的锤子就越好,能解决实际工作内容的就行。

    有时候与其学着各种各样的新技术新框架,不如陪家人看看电影、逛逛街,我们不是互联网的螺丝钉,我们是人,只是恰逢资本主义时代,大多数人都被异化成了“工具人”,但我们都有自己的生活,自己的家人、朋友,每个人都不一样,都有自己的人生。

    总而言之,目前市场上响应式编程各种各样,定义五花八门,优点论证也不够充足,大家还是不要急着入场。
    在这里插入图片描述

    相关文档

    1. http://reactivex.io/intro.html
    2. GitHub rxjava
    3. Reactive-Programming-一种技术-各自表述
    4. 响应式宣言
    5. 响应式宣言词汇表
    展开全文
  • RsJava 响应式编程, 高清带目录. 响应式编程是一种基于异步数据流概念的编程模式。在开发手机 App、 Web App 时, 要想保证对用户 请求的实时响应,给用户带来流畅的体验,响应式编程是一个不错的选择, RxJava 则是...
  • 通过研究rxjava,从中得到启发,自己重写了一个精简的响应式编程框架,这套框架与rxjava用法类似,采用链式调用规则,代码更精简,结构轻巧,扩展性强。此框架目前处在雏形阶段,希望能够抛砖引玉,大家有什么宝贵...
  • 理解java响应式编程

    原文:Understanding reactive programming in Java
    https://nullbeans.com/understanding-reactive-programming-in-java/

     

       这篇文章我们将讨论响应式编程的原理,它要解决的问题,以及java响应式编程的基础。这篇教程聚集于java响应式编程的用法,但其中讨论的原理和思路同样适用于其它编程语言。

        这篇文章可能读起来很长,但如果你对响应式编程有疑问,并且不知道从何处开始,或者对于java响应式编程难于找到好的信息来源,那么这篇文章会是一个好的开始并能帮你澄清很多主题。


    目录

    响应式编程要解决什么问题?

    响应式程序的执行

    响应式编程是什么?

    响应式声明

    什么是背压(Backpressure)

    Java响应式编程

    发布者(Publisher)

    订阅者(Subscriber)

    订阅(Subscription)

    处理器(Processor)

    综述

    总结


    响应式编程要解决什么问题?

        当我开始研究响应式编程时,我可能会读到像这样的定义:响应式编程是关注于数据交换和传播的编程范式。然而,这一定义丢掉了这一编程范式的核心且并没有更多的解决。

        那么,我们试着把事情简化一下,只强调传统命令式程序执行和异步“响应”执行之间的不同之处。

        一个程序由一系列计算步骤组合而成,它们需要按特定的顺序执行。传统程序执行时,线程一次只执行一个步骤。我们以快餐店为例。我们假设在收银台只有一个服务员。这个收银员负责接单,然后厨师将食物做好后打包食物。

        每个顾客会直到柜台点餐。服务员将订单传给厨师,在食物准备好前会等待几分钟,然后打包并递给顾客。然后,服务员开始接下一个顾客下的订单。

        这种方式的问题在于,由于浪费了空闲时间所以没有效率。首先,服务员等待厨师制作食物时时间就已浪费了。在此期间,除了等待没做任何事情。同时,厨师当服务员接下一个顾客的订单时也处于空闲状态。

    程序同步执行的例子

        在这个例子中,服务员代表一个线程,而厨师代表一个数据库,顾客的订单代表用户输入。在传统模式中程序执行时,比如,获取一个REST请求,线程将首先将请求转化为数据库查询,然后发送到数据库,等待它的返回,一旦获取返回,线程处理完成后就会给顾客一个响应。

        在线程等待数据库返回时,线程处于阻塞状态。这将导致程序执行无效率而且还慢。尽管可以增加线程池中可用线程数,但每个线程自身也会有内存开销,最终还是会受到处理器核心数的限制。

        同时,如果应用依赖于i/o系统,比如网络资源或数据库,添加更多的线程不会提高由i/o时廷造成的性能问题。

        总之,响应式编程的目是帮助应用在不同的环境条件和负载下仍保持响应性。

     

    响应式程序的执行

        响应式执行结合了一些异步执行的原则,并以一种特定模式运行,这种模式我们可以通过“响应式编程”来定义并控制。

        我们回顾一下快餐店的例子。在响应式执行场景中,服务员(线程)从顾客那是接单(用户输入),然后传给厨师(数据库)。服务员非但没有等待厨师完成订单,他告诉顾客(订阅者)一旦订单完成会通知他们(通过订阅)。服务员会继续从下一个顾客那里接单并执行相同的步骤。

        服务员会一直接顾客的订单直到厨师通知服务员一笔订单已做完。当订单已完成,服务员会递给顾,客顾客的请求也随之完成。

        这种方法以两种方式提高了效率。首先,服务员没以空闲等待。接着,厨师可以收到稳定的订单借给去制作食物,使得厨师的资源更充分的被利用。这样也会提高顾客的体验,因为他们会更快地被接待且订单会被处理的更快,而不会排长队等待得不到接待。

    异步响应式执行。服务员接单传给厨师,然后再接更多的订单,这是一种执行然后忘记模式

        这就是传统同步执行与异步响应式执行之间最大的不同。也就是说,响应式编程能在线程级别提高执行效率。

     

    响应式编程是什么?

        现在我们知道响应式程序是怎么执行的,也就是说,响应式编程是一种编程范式,基于它的API、库和语言特性会采用特定的设计模式,这种设计模式的目的是完成异步响应式程序的执行。我们将在下面的章节探索响应式设计模式。

     

    响应式声明

        应用如果要变成响应式的,它需要拥有特定的属性。这些属性被定义在现在称为“响应式声明”中,它使得“响应式的”就用不同于异步应用。

        应用如果要变成响应式的,它需要具有:

    可应答的(Responsive):系统需要及时对请求进行应答。可应答的系统应该具有快速和一致的响应时间。

    弹性的(Resilient):一旦出现故障,系统应仍可提供应答。例如,用户尝试访问一个出错的网站,网站应给用户回复一个好的错误页面而不是什么也不回复。

    可伸缩的(Elastic):一个可伸缩的系统可适应不同的负载。例如,负载达到峰值时可对资源扩容,负载变低时可释放资源。可伸缩的系统在高负载时仍应是可应答的。

    消息驱动的(Message Driven):响应式系统利用异步消息驱动的通讯机制(服务员告诉顾客一旦订单完成就会通知)。这样资源使用效率更高,故障隔离性和容忍性会更好。想像一下你的系统正在使用可能会随时挂掉的不稳定的数据库。如何使用传统阻塞调用,每次会有一个应用线程因调用数据库而挂起,这个线程会被阻塞很长时间。这会使应用中剩下的可用线程变少。异步消息驱动的通讯方式可以解决这种问题。

        注意这4 个原则仅仅只是原则。没有系统可以免于故障或性能降级。然而,你的目标是建设可响应的系统,所以要尽可能的遵从这些原则。

        响应式声明是对可响应的系统一般性理解,它由技术工业领域里的一些个人或组织总结的。你可以在这里看到更多关于它的内容。

     

    什么是背压(Backpressure)

    背压是另外一个关于数据流速控制复杂名词。它是为了提高系统的稳定性和完整性才被使用的。

    拿一个处理用户查询的应用来举例。系统会处理用户发送来的每一个请求。然而,如果一个用户请求发的又多又快,他们会使系统变慢或使它挂掉,并降低其他用户的体验(比如服务拒绝攻击)。

    背压试图通过限制在指定时间内允许的操作数来解决这个问题(也就是限制执行速率)。

    响应式编程可以采用多种策略实现背压,比如使用缓存或拒绝请求。我们会在另一篇文章中探讨这些策略。

     

    Java响应式编程

    如果你搜索Java响应式编程,你很可能会被网上不同的实现和不同教程和文章中的代码所困惑。这是有原因的。

    当前,Java中没有标准统一的响应式API实现。当前有大量的库提供不同的实现,以及工具运行响应式编程。

    从RxJava 1 和2,Java SDK 9中引入的Flow API ,Reactive Streams,到Project Reactor (Spring在使用的)和 Akka Streams,这里只列举其中的一些。

    需要记住的重要事情是这些框架都基于相同的设计模式,它们中的每一种都或多或少的提供开箱即用的功能和方便使用的类。我们将在后面的教程中探索这些不同的库。

    我们将聚焦于大多数框架基于的基本设计模式。最终要选择哪个库由你自己来定。

    我们以定义响应式程序的基本组件开始,在最后我们会总结一下它们一起是怎么工作的。

     

    发布者(Publisher

    发布者就是数据生产者。这个组件为系统产生想要的数据。在实践中,这可能是一个数据库的查询结果、twitter feed、股票市场报价feed,等等。

    发布者没有名字...或者说许多名字。它依赖于响应式库的选择。

    • Observable (RxJava) / Mono (Project Reactor): 这种不产生任何数据的发布者有许多名字。在Reactive Streams的规范中,它就叫做发布者。
    • Single (RxJava) / Mono (Project Reactor): 这种最多产生一条数据的发布者有许多名字。在Reactive Streams的规范中,它就叫做发布者。
    • Observable (RxJava) / Flux (Project Reactor): 这种产生多条数据的发布者有许多名字。在Reactive Streams的规范中,它仍就叫做发布者。

     

    订阅者(Subscriber

    订阅者“订阅”发布者,当新数据产生、错误发生、或发布者完成数据生产后会收到通知。产生的数据会在订阅者中进行处理。

    幸运的是,订阅者在RxJava和Project Reactor中还是被叫做订阅者。

    订阅者有3个数据通道。每一个通道都是通过订阅者的内部方法进行通知。

    • OnNext:发布者产生一条或多条数据项时会调用此方法。
    • OnError:发布者在生成数据过程中产生错误时会调用此方法。
    • OnComplete:此方法被调用说明发布者数据生产已完成,不会再数据产生了。

    请注意以上方法可以在调用方线程或单独的线程被调用,这依赖于你的配置。

    最后要讨论的是OnSubscribe方法。这个方法只会在订阅创建时被调用一次。注意它不被看作是数据通道。它被用来设置订阅者以及从订阅中请求第一条数据。

     

    订阅(Subscription

    订阅是一个订阅者和发布者之间的合约。订阅者使用它从发布者那里请求更多的数据项,或者取消订阅中止接收事多的数据。

    订阅者能通过订阅中的请求方法从发布者那里请求后续1~n条数据。这个通常在订阅者的onSubscribe和onNext方法中完成。

     

    处理器(Processor

    处理器是一种即可扮演订阅者又可扮演发布者的响应式实体。它即能消费由发布者产生的数据项,也可以自己发布数据。

    处理器通常在发布者和消费者之间安装,用来处理中间数据项。比如,你可以创建处理器对发布者产生的所的单词执行拼写检查。这种情况下,处理器作为订阅者。处理器发布更正过的单词给它的订阅者们,这时它又成为了发布者。

     

    综述

    一张图胜过千言万语。所以我看一下下面的图:

    响应式程序的执行例子

     

    在一般的响应式程序执行过程中,总是以订阅者订阅发布者开始。一旦发布者与订阅者之间的订阅成功创建,订阅者会使用订阅中的请求方法请求数据。

    当发布者发布新数据时,订阅者的onNext方法被调用。订阅者能请求更多数据或取消订阅。在我们的例子中,订阅者请求更多数据。

    一旦发布者没有数据楞发布了,订阅者的onComplete方法会被调用,说明合约(订阅)完成并结束。

     

    总结

    响应式编程已经有一段时间了。然而,技术行业最终开始关注这一设计模式是由于对更好地响应时间的要求、更严格地可靠性要求以及微服务架构的兴起。

    在i/o场景中为了更好的利用可用系统资源以及提高应用响应时间,我们在这个教程中讨论了使用响应式编程的优点。

     

     

     

    展开全文
  • google为android打造的响应式编程agera,类似rxjava与rxandroid、rxbus、rxbinding的结合体,提供五大核心:content、database、net、rvdatabinding、rvadapter
  • 响应式编程规范

    千次阅读 2019-02-01 14:40:51
    响应式编程的概念已经很早就提出来了,业内很多大牛共同构建了 响应式宣言(中文版)。如果您认可该宣言,可以在其中签下自己的大名。 内容不多,这里我们直接拷贝过来。 在不同领域中深耕的组织都在不约而同地尝试...

    响应式编程系列文章

    响应式宣言

    响应式编程的概念已经很早就提出来了,业内很多大牛共同构建了 响应式宣言(中文版)。如果您认可该宣言,可以在其中签下自己的大名。
    内容不多,这里我们直接拷贝过来。
    在不同领域中深耕的组织都在不约而同地尝试发现相似的软件构建模式。 希望这些系统会更健壮、更具回弹性 、更灵活,也能更好地满足现代化的需求。

    近年来,应用程序的需求已经发生了戏剧性的更改,模式变化也随之而来。仅在几年前, 一个大型应用程序通常拥有数十台服务器、 秒级的响应时间、 数小时的维护时间以及GB级的数据。 而今,应用程序被部署到了形态各异的载体上, 从移动设备到运行着数以千计的多核心处理器的云端集群。 用户期望着毫秒级的响应时间,以及服务100%正常运行(随时可用)。 而数据则以PB计量。 昨日的软件架构已经根本无法满足今天的需求。

    我们相信大家需要一套贯通整个系统的架构设计方案, 而设计中必需要关注的各个角度也已被理清: 我们需要系统具备以下特质:即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)。 对于这样的系统,我们称之为反应式系统(Reactive System)。

    使用反应式方式构建的反应式系统会更加灵活、松耦合、可伸缩。 这使得它们的开发和调整更加容易。 它们对系统的失败 也更加的包容, 而当失败确实发生时, 它们的应对方案会是得体处理而非混乱无序。 反应式系统具有高度的即时响应性, 为用户提供了高效的互动反馈。

    反应式系统的特质

    • 即时响应性 :只要有可能, 系统就会及时地做出响应。 即时响应是可用性和实用性的基石, 而更加重要的是,即时响应意味着可以快速地检测到问题并且有效地对其进行处理。 即时响应的系统专注于提供快速而一致的响应时间, 确立可靠的反馈上限, 以提供一致的服务质量。 这种一致的行为转而将简化错误处理、 建立最终用户的信任并促使用户与系统作进一步的互动。

    • 回弹性:系统在出现失败时依然保持即时响应性。 这不仅适用于高可用的、 任务关键型系统——任何不具备回弹性的系统都将会在发生失败之后丢失即时响应性。 回弹性是通过复制、 遏制、 隔离以及委托来实现的。 失败的扩散被遏制在了每个组件内部, 与其他组件相互隔离, 从而确保系统某部分的失败不会危及整个系统,并能独立恢复。 每个组件的恢复都被委托给了另一个(外部的)组件, 此外,在必要时可以通过复制来保证高可用性。 (因此)组件的客户端不再承担组件失败的处理。

    • 弹性: 系统在不断变化的工作负载之下依然保持即时响应性。 反应式系统可以对输入(负载)的速率变化做出反应,比如通过增加或者减少被分配用于服务这些输入(负载)的资源。 这意味着设计上并没有争用点和中央瓶颈, 得以进行组件的分片或者复制, 并在它们之间分布输入(负载)。 通过提供相关的实时性能指标, 反应式系统能支持预测式以及反应式的伸缩算法。 这些系统可以在常规的硬件以及软件平台上实现成本高效的弹性。

    • 消息驱动:反应式系统依赖异步的消息传递,从而确保了松耦合、隔离、位置透明的组件之间有着明确边界。 这一边界还提供了将失败作为消息委托出去的手段。 使用显式的消息传递,可以通过在系统中塑造并监视消息流队列, 并在必要时应用回压, 从而实现负载管理、 弹性以及流量控制。 使用位置透明的消息传递作为通信的手段, 使得跨集群或者在单个主机中使用相同的结构成分和语义来管理失败成为了可能。 非阻塞的通信使得接收者可以只在活动时才消耗资源, 从而减少系统开销。
      在这里插入图片描述
      大型系统由多个较小型的系统所构成, 因此整体效用取决于它们的构成部分的反应式属性。 这意味着, 反应式系统应用着一些设计原则,使这些属性能在所有级别的规模上生效,而且可组合。世界上各类最大型的系统所依赖的架构都基于这些属性,而且每天都在服务于数十亿人的需求。现在,是时候在系统设计一开始就有意识地应用这些设计原则了, 而不是每次都去重新发现它们。

    reactive-streams

    官网参见:Reactive Streams
    这里只列举出一些核心的点,完整详细内容请参见官网。

    Reactive Streams是一种非阻塞、响应式、异步流处理、支持背压的标准。包括针对运行时环境(JVM和JavaScript)以及网络协议。

    JDK9 中提供了响应式编程的规范: java.util.concurrent.Flow。一些组件会采用响应式规范来编写,比如java11中提供的支持http/2的HTTP/2 Client API,他不仅可以像Apache HTTPClient、OKhttp一样好用,而且是 JDK 在 Reactive-Stream 方面的第一个生产实践,广泛使用了 Java Flow API。具体请看java11中的java.net.http包。

    Reactive-Stream提供的是一个编程规范,致力于提供非阻塞、响应式、异步流处理、支持背压的策略。不同组织或者语音都可以基于这个规范编写自己的实现。比如现在流行的RxJava、Reactor、AKKA等。以上不同实现都是基于JVM的,都实现了标准的响应式编程规范,原则上,他们之间可以互操作,可以共享内存堆在JVM中的对象,在线程之间传递流。

    Reactive Streams 1.0.2 文档

    展开全文
  • 响应式编程在Android中的应用

    千次阅读 2020-08-13 01:46:20
    响应式编程简介 响应式编程的具体实现-RxJava 基本概念 RxJava的四种角色 热Observable和冷Observable Observable创建符 Subject 直接创建 Observable 从列表创建 Observable 具有特殊功能的创建符 过滤Observables ...
  • Spring5.0响应式编程入门

    万次阅读 2018-06-14 09:35:29
    引言​ 响应式编程是一种面向数据流和变化传播的编程范式。使用它可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。我们可以使用声明的方式构建应用程序的...
  • 1. SpringBoot学习笔记十七:springBoot2.x的响应式编程 文章目录1. SpringBoot学习笔记十七:springBoot2.x的响应式编程1.1. 什么是响应式编程1.2. 响应式编程的两个对象Mono和Flux1.3. 响应式编程的两种接口风格...
  • 函数响应式编程

    2017-08-16 09:26:47
    一次内部分享的PPT,从函数式编程的优点到响应式结合原因,Rx的周期,应用的举例,源代码的解读,到MVVM的应用的介绍
  • java9 响应式编程支持

    千次阅读 2019-02-01 14:52:57
    文章目录概述响应式编程接口demo 概述 java9开始,官方支持了响应式编程规范,提供了顶级的响应式编程接口。 java11开始,官方提供了支持http2的、友好的http客户端java.net.http,该客户端就是jdk内部第一个基于...
  • 第2章 响应式编程思想概述—概念与案例讲解 第3章 RxJava基本元素—源码解析与案例实践 第4章 Operator操作符变换—源码解析与案例实践 第5章 Scheduler线程变换—源码解析与案例实践 第6章 整体变换compose和...
  • 函数式编程 防御式编程 响应式编程 契约式编程
  • 响应式编程简介之:Reactor

    万次阅读 2020-11-06 09:12:47
    其中Flux 代表的是 0 to N 个响应式序列,而Mono代表的是0或者1个响应式序列。 我们看一个Flux是怎么transfer items的: 先看下Flux的定义: public abstract class Flux<T> implements Publisher<T> 可以看到Flux...
  • 昨天测试了一下reactior库,发现响应式编程其实是一个数据流,然后用处理函数订阅这个数据流,当数据流发生变化时,处理函数会被执行,而传统的命令式编程,当有数据变化时,比如有条请求上传到服务器,然后程序直接...
  • SpringBoot响应式编程(整理一)

    千次阅读 2019-09-11 15:11:07
    1、SprinBoot响应式编程简介 基础理解: 依赖于事件,事件驱动(Event-driven) 一系列事件称为“流” 异步 非阻塞 观察者模式 (1)Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架。 与Spring MVC...
  • 什么是函数响应式编程响应式编程思想为体,函数式编程思想为用。首先我们要来了解什么是函数式编程和响应式编程。 什么是函数式编程? 顾名思义,函数式编程就是用函数来解决问题的编程方式,几乎任何一门语言都...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 169,317
精华内容 67,726
关键字:

响应式编程