18 | 反应式编程框架设计:如何使程序调用不阻塞等待,立即响应?
该思维导图由 AI 生成,仅供参考
反应式编程
- 深入了解
- 翻译
- 解释
- 总结
反应式编程框架设计:如何使程序调用不阻塞等待,立即响应? 本文介绍了反应式编程作为解决高并发情况下程序崩溃问题的方案。通过异步编程、多线程和异步I/O访问等技术,实现程序调用非阻塞、即时响应的特性。主流的反应式编程框架有RxJava、Reactor和Flower,它们基于观察者设计模式和函数式编程,实现了异步无阻塞的调用。Flower框架利用了Web容器的异步特性和异步的数据库驱动,实现了几乎没有任何地方会被阻塞的特性。文章还介绍了Flower框架的设计方法,包括对Actor进行封装,编写细粒度的Service,并支持可视化的Service流程编排。Flower框架在部分项目中落地应用,显著提高系统性能和可用性。它不仅是一个反应式Web编程框架,还是反应式的微服务框架,提供了分布式非阻塞的微服务系统。反应式编程虽然带来性能和可用性提升,但也可能存在问题,需要谨慎应对。欢迎读者尝试并分享交流。
《后端技术面试 38 讲》,新⼈⾸单¥59
全部留言(26)
- 最新
- 精选
- Paul Shan高并发系统,传统解决方案的弊端在于调度的单元是线程,当IO操作时,线程做无谓地等待,相应的CPU资源白白浪费,线程数目多到一定程度,系统就会被压垮。 反应式编程的第一个目标即时响应,就是异步非阻塞的,遇到IO操作就返回,通过回调函数来取结果。 反应式系统第二个目标回弹性,系统有一定的自我修复功能,个人以为这和反应式编程的本质没太大关系,系统自我修复和错误处理是任何系统都想要的功能,和反应式编程关系不大,这里可能和微服务的关系更大,不知道老师如何看这个问题。 反应式系统第三个目标是弹性,反应式编程在数据的请求和回调存在间隙,系统需要合理安排资源,让这个间隙全局而言最小。 反应式编程第四个目标是消息驱动,反应式编程在数据请求和消费解耦了,需要用另外的机制串起来,消息驱动就是其中一种串法。 反应式编程通过分离数据请求和数据消费以达到有效利用CPU和IO资源,提高并发的目的。我个人以为反应式编程是编程的未来,因为异步才是数据流转的本质。传统操作系统成型的时候CPU只有一颗,那时同步编程思想是主流。现在多核系统已经是主流,异步编程更为高效。 反应式编程本身的问题就是得学一种新的编程范式,像rxjava学习曲线还是挺陡峭的。反应式编程拆分了请求数据和消费数据,通过消息来驱动可能带来数据的多次拷贝,函数式编程尤其强调数据的不可更改,只好通过拷贝来解决,本质上是一种用空间换时间的策略,会消耗更多的内存。异步编程调错总归有些麻烦,这也是成本之一。
作者回复: 👍
2020-01-08238 - 草原上的奔跑异步的调用一般比较难调试,运行正常的时候性能好、可用性高,但出问题后debug比较困难,不知道李老师你们是如何处理的
作者回复: 异步难调试主要是因为异步的代码执行在不同的线程上,导致没有统一的调用栈,异常的时候不知道哪里出错的。Flower通过流程编排的方式管理异步方法代码,出错的时候可以通过流程定位异常,对调试定位有帮助。
2020-01-01224 - 蚂蚁内推+v请教一下老师,我理解的异步非阻塞调用其实就是将耗时操作放到了另外的线程池中,这个感觉对性能上没有多大提升啊,比如我了解到的reactor
作者回复: 1 不是放入线程池中,是放入队列中,等待线程执行,这样就只需要较少的线程,执行大量的操作,减少线程启动和调度,性能更好 2 对于IO操作,非阻塞意味着不会不会阻塞线程,避免线程资源浪费,性能更好 3 性能不只是响应时间或者处理速度,异步操作也许不能降低响应时间,但是可以处理更多请求,也是提升性能,具体参考高性能一篇专栏
2020-02-2329 - Jagger Chen老师您好,关于即时响应,如果程序还没计算出结果,响应什么给调用端呢?
作者回复: 即时响应的目的是为了不阻塞调用端线程,提高处理能力。 调用端为什么需要得到计算结果,为了下一步计算?那被调用者把自己的计算结果传递给自己的下一个被调用者就可以了。 你可以看下Flower的web开发demo,http response不是Controller返回的,而是计算出客户端结果的那个service调用web.print返回的。这样在计算过程中,可以随时返回response,而不用等到全部处理完在返回。
2020-06-2846 - 老男孩李老师和专栏的朋友们新年快乐!哈哈!又一年了。虽然我还在现实的苟且中徘徊,但依然算是不忘初心吧。用一句现在很流行的话就是,愿大家只争朝夕,不负韶华。之前研究了一下spring的webflux发现目前异步编程在数据库驱动这块对关系型数据库的支持不太好,比如myspl。还有诺诺的问一下,mailbox是不是一个内存队列?不知道flower能不能支持用第三方的消息队列来替换mailbox的工作?还有actor里边是不是用到模板设计模式了?
作者回复: 新年快乐。异步数据库驱动还是有一些的,但是因为业界用的不多,所以都不怎么维护。反应式编程的大气候还是没起来。
2020-01-014 - Jagger Chen老师您好,同步编程中使用 ThreadLocal 来跨类传递状态,在响应式编程模型中如何做呢?这个算不算是一个弊端?
作者回复: 消息驱动的反应式框架,比如flower,可以通过消息传递状态。
2020-06-283 - 蚂蚁内推+v老师,回调函数由谁来执行呢?比如线程1异步调用某方法,由线程2执行方法,那线程2执行完之后谁来执行回调函数呢
作者回复: Flower中没有调用,也就没有回调。 服务经过编排后,由框架异步执行服务。 一个服务执行完,他的结果不是返回给他的上一个服务,而是发送给他的下一个服务。
2020-02-263 - 麋鹿在泛舟“反应式实践其实更多落地就是在前端,发送请求后就不管了,然后等到异步响应到达后异步更新页面。” 所以对于后端系统来说,怎么应对阻塞呢?
作者回复: 阻塞基本上都是IO阻塞,使用异步IO即可,如文中所述。
2020-01-202 - 饭饭这样流程编排的为什么不用akka stream?有什么考虑嘛?
作者回复: 编程模型不同,我们认为Flower编程模型更加友好,事实如何,我们将来再看。
2020-01-102 - 托尼斯威特请问一个细节: "Actor 则会在从 Mailbox 里面去获取消息,对消息进行异步的处理". 消息的处理结果如何返回给Sender呢? Sender如果不靠回调函数, 又是如何知道怎么处理返回来的结果的呢?
作者回复: 在actor里给sender发消息,把处理结果发送过去
2020-12-241