首页 > 其他分享 >响应式流的核心机制——背压机制

响应式流的核心机制——背压机制

时间:2024-04-06 17:46:08浏览次数:474  
标签:消费者 队列 背压 模式 响应 机制 生产者

一、响应式流是什么?

响应式流旨在为无阻塞异步流处理提供一个标准。它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者,而不需要发布者阻塞,或订阅者有无限制的缓冲区或丢弃。

响应式流模型存在两种基本的实现机制。一种就是传统开发模式下的“拉”模式,即消费者主动从生产者拉取元素;而另一种就是“推”模式,在这种模式下,生产者将元素推送给消费者。相较于“拉”模式,“推”模式下的数据处理的资源利用率更好,而不需要发布者阻塞,或订阅者有无限的缓冲区或丢弃。

响应式流模型存在两种基本的实现机制。一种就是传统开发模式下的“拉”模式,即消费者主动从生产者拉取元素;而另一种就是“推”模式,在这种模式下,生产者将元素推送给消费者。相较于“拉”模式,“推”模式下的数据处理的资源利用率更好,下图所示的就是一种典型的推模式处理流程。

上图中,数据流的生产者会持续的生产数据并推送给消费者。这里就引出流量控制的问题,即如果数据的生产者和消费者处理数据的速度时不一致的,我们该如何确保系统的稳定性?

二、流量控制

2.1 生产者生产数据的速率小于消费者的场景
这种场景对于消费者来说没啥压力,正常消费就好了,这里也就不需要所谓的流量控制了。

2.2 生产者生产数据的速率大于消费者的场景
生产者生产数据的速率大于消费者的场景,应该是我们业务中经常遇到的场景了,这种场景由于消费者处理不过来导致崩溃,通常的做法是在生产者与消费者之间加一个队列做缓冲。我们知道队列具有存储和转发功能,所以可以用它来进行一定的流量控制。

如何对于流量进行很好的控制?这就转变到了如何设计好一个队列了,目前 Java 业界主流的队列有以下三种:

  1. 无界队列
    见名知意,无界队列在原则上是拥有无线大小容量的队列,可以存放生产者产生的所有消息。

  2. 有界丢弃队列
    为了避免上面无界队列的弊端,有界丢弃队列采用的是如果队列满了,就会采用丢弃后面传入的值,这里可以设置一些丢弃策略,比如说按照优先级或先进先出等。

  3. 有界阻塞队列
    像一些支付金融级别的场景,是不允许丢数据的,所以我们引出有界阻塞队列,我们会在队列消息数量达到上限后阻塞生产者,而不是直接丢弃消息。

所以,无论从回弹性、弹性还是即时响应性出发,上述的队列都不是响应式流的上佳解决办法。

三、背压机制
上面说的那几种队列纯“推”模式下的数据流量会有很多不可控制的因素,并不能直接应用,而是需要在“推”模式和“拉”模式之间考虑一定的平衡性,从而优雅地实现流量控制。这就需要引出响应式系统中非常重要的一个概念——背压机制(Backpressure)。

什么是背压?简单来说就是下游能够向上游反馈流量请求的机制。通过前面的分析,我们知道如果消费者消费数据的速度赶不上生产者生产数据的速度时,它就会持续消耗系统的资源,直到这些资源被消耗殆尽。

这个时候,就需要有一种机制使得消费者可以根据自身当前的处理能力通知生产者来调整生产数据的速度,这种机制就是背压。采用背压机制,消费者会根据自身的处理能力来请求数据,而生产者也会根据消费者的能力来生产数据,从而在两者之间达成一种动态的平衡,确保系统的即时响应性。

标签:消费者,队列,背压,模式,响应,机制,生产者
From: https://www.cnblogs.com/wuhaoxin/p/18113506

相关文章

  • 线程等待通知机制
    join()是等待线程结束。wait是等待线程通知,并不一定是执行结束。能更加精细的控制线程执行的顺序。在什么情况下使用线程等待通知呢?“线程饿死问题”,一个线程频繁的获取锁和释放锁,由于获取锁的速度太快,其他的线程抢不到,那么就会影响到代码的执行速度。而等待通知机制就......
  • Flask 请求与响应
    request.args ->请求Query参数request.form->请求Body参数request.values->请求所有参数分别代表什么?测试:发一个post请求 结果: 请求相关信息:常用的还有request.cookies,request.headers,request.path保存文件跟Django不一样文件对象=request.file......
  • 深入理解Java异常处理机制(day20)
    异常处理异常处理是程序运行过程产生的异常情况进行恰当的处理技术在计算机编程里面,异常的情况比所我们所想的异常情况还要多。Java里面有两种异常处理方式;1.利用try···catch···finaly语句处理异常,优点是分开了处理异常代码和程序正常代码,增强了程序的可读性,减少......
  • JVM类加载机制有哪些?
    全盘负责,当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入父类委托,先让父类加载器试图加载该类,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类缓存机制,缓存机制将会保证所有加......
  • Spark面试整理-解释Spark中的内存管理和持久化机制
    在Apache Spark中,内存管理和持久化机制是核心特性,它们对于提高大规模数据处理的效率和性能至关重要。内存管理统一的内存管理:Spark使用统一的内存管理模型,将执行内存(用于计算如shuffle、join等)和存储内存(用于缓存数据如RDDs)合并在一起。这种模型提供了更高的灵活性和效......
  • Python程序设计 垃圾回收机制&鸭子类型
    1.简介引用计数(python默认):记录该对象当前被引用的次数,每当新的引用指向该对象时,它的引用计数ob_ref加1,每当该对象的引用失效时计数ob_ref减1,一旦对象的引用计数为0,该对象立即被回收标记清除:第一段给所有活动对象标记,第二段清除非活动对象分代回收:python将内存根据对象的存......
  • 【系统深入学习GO】Go 的并发机制-原理探究 线程实现模型
    在操作系统提供的内核线程之上,Go搭建了一个特有的两级线程模型。*两级线程模型:两级线程模型也称为多对多(M:N)的线程实现。与其他模型相比,两级线程模型提供了更求的灵活性。在此模型下,一个进程可以与多个KSE相关联,这与内核级线程模型相似。但与内核级线程模型不同的是,进程......
  • 使用注意力机制的 LSTM 彻底改变时间序列预测
    目录一、说明二、LSTM和注意力机制简介三、为什么要将LSTM与时间序列注意力相结合?四、模型架构训练与评估五、验证六、计算指标七、结论一、说明  在时间序列预测领域,对更准确、更高效的模型的追求始终存在。深度学习的应用为该领域的重大进步铺平了道路,其中......
  • Python进阶:使用requests库轻松发送HTTP请求并获取响应
    Python进阶:使用requests库轻松发送HTTP请求并获取响应简介:本文将带您深入了解Python中强大的requests库,学会如何使用它发送各种HTTP请求,并轻松获取响应内容。无论您是初学者还是有一定经验的Python开发者,本文都将为您提供实用、详细的指导,助您在网络请求与响应的处理上更上......
  • SCI一区 | Matlab实现NGO-TCN-BiGRU-Attention北方苍鹰算法优化时间卷积双向门控循环
    SCI一区|Matlab实现NGO-TCN-BiGRU-Attention北方苍鹰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测目录SCI一区|Matlab实现NGO-TCN-BiGRU-Attention北方苍鹰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介......