RabbitMQ4:work模型

欢迎来到“雪碧聊技术”CSDN博客!

在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将不断探索Java的深邃世界,分享最新的技术动态、实战经验以及项目心得。

让我们一同在Java的广阔天地中遨游,携手提升技术能力,共创美好未来!感谢您的关注与支持,期待在“雪碧聊技术”与您共同成长!

目录

一、work模型?

1、什么是work模型?

2、案例

①案例介绍

②具体操作

③观察上述现象:无论两个消费者的消费速度一致,还是不一致,最终二者消费的消息数量都是25条(平分,一人从队列取一半)。

3、为何会出现上述问题?

4、如何解决上述问题?

5、根据上述的思路,解决该问题

二、总结

1、知识总结

2、面试题:如何避免消息堆积问题?

①给队列上绑定多个消费者(work模型),从而提高消费速度

②优化代码,使代码执行速度变快,消费速度也就变快了

③rabbitMQ的默认规则:队列中的同一条消息,只能被一个消费者消费。即:不会出现两个消费者消费同一条消息的现象,从而提高消费速度。

④通过设置prefetch,来控制消费者手里最多有1条消息,不允许堆积消息,实现能者多劳。(最重要的一点)


一、work模型?

1、什么是work模型?

        work queues,是一种任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息。

        注意:rabbitMQ默认同一条消息只能被一个消费者消费。

        即:不会出现两个消费者消费同一条消息的现象。

2、案例

①案例介绍

②具体操作

  • 第一步:创建一个队列work.queue

  • 第二步:编写生产者代码,1秒的时间,向队列work.queue发送50条消息

运行结果:

  • 第三步:编写监听者代码,监听队列work.queue的消息
@Component //交给spring管理
public class MqListener {@RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg){//消费者1System.out.println("消费者1 收到了 work.queue的消息... :【" + msg + "】");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg){//消费者2System.err.println("消费者2 收到了 work.queue的消息... :【" + msg + "】");}}

运行结果:

消费者1 收到了 work.queue的消息... :【hello, work, message_1】
消费者2 收到了 work.queue的消息... :【hello, work, message_2】
消费者1 收到了 work.queue的消息... :【hello, work, message_3】
消费者2 收到了 work.queue的消息... :【hello, work, message_4】
消费者1 收到了 work.queue的消息... :【hello, work, message_5】
消费者2 收到了 work.queue的消息... :【hello, work, message_6】
消费者1 收到了 work.queue的消息... :【hello, work, message_7】
消费者2 收到了 work.queue的消息... :【hello, work, message_8】
消费者1 收到了 work.queue的消息... :【hello, work, message_9】
消费者2 收到了 work.queue的消息... :【hello, work, message_10】
消费者1 收到了 work.queue的消息... :【hello, work, message_11】
消费者2 收到了 work.queue的消息... :【hello, work, message_12】
消费者1 收到了 work.queue的消息... :【hello, work, message_13】
消费者2 收到了 work.queue的消息... :【hello, work, message_14】
消费者1 收到了 work.queue的消息... :【hello, work, message_15】
消费者2 收到了 work.queue的消息... :【hello, work, message_16】
消费者1 收到了 work.queue的消息... :【hello, work, message_17】
消费者2 收到了 work.queue的消息... :【hello, work, message_18】
消费者1 收到了 work.queue的消息... :【hello, work, message_19】
消费者2 收到了 work.queue的消息... :【hello, work, message_20】
消费者1 收到了 work.queue的消息... :【hello, work, message_21】
消费者2 收到了 work.queue的消息... :【hello, work, message_22】
消费者1 收到了 work.queue的消息... :【hello, work, message_23】
消费者2 收到了 work.queue的消息... :【hello, work, message_24】
消费者1 收到了 work.queue的消息... :【hello, work, message_25】
消费者2 收到了 work.queue的消息... :【hello, work, message_26】
消费者1 收到了 work.queue的消息... :【hello, work, message_27】
消费者2 收到了 work.queue的消息... :【hello, work, message_28】
消费者1 收到了 work.queue的消息... :【hello, work, message_29】
消费者2 收到了 work.queue的消息... :【hello, work, message_30】
消费者1 收到了 work.queue的消息... :【hello, work, message_31】
消费者2 收到了 work.queue的消息... :【hello, work, message_32】
消费者1 收到了 work.queue的消息... :【hello, work, message_33】
消费者2 收到了 work.queue的消息... :【hello, work, message_34】
消费者1 收到了 work.queue的消息... :【hello, work, message_35】
消费者2 收到了 work.queue的消息... :【hello, work, message_36】
消费者1 收到了 work.queue的消息... :【hello, work, message_37】
消费者2 收到了 work.queue的消息... :【hello, work, message_38】
消费者1 收到了 work.queue的消息... :【hello, work, message_39】
消费者2 收到了 work.queue的消息... :【hello, work, message_40】
消费者1 收到了 work.queue的消息... :【hello, work, message_41】
消费者2 收到了 work.queue的消息... :【hello, work, message_42】
消费者1 收到了 work.queue的消息... :【hello, work, message_43】
消费者2 收到了 work.queue的消息... :【hello, work, message_44】
消费者1 收到了 work.queue的消息... :【hello, work, message_45】
消费者2 收到了 work.queue的消息... :【hello, work, message_46】
消费者1 收到了 work.queue的消息... :【hello, work, message_47】
消费者2 收到了 work.queue的消息... :【hello, work, message_48】
消费者1 收到了 work.queue的消息... :【hello, work, message_49】
消费者2 收到了 work.queue的消息... :【hello, work, message_50】

由于此时两个消费者的消费速度一致(因为方法代码量相同),因此一人消费25条消息。 

  • 第四步:我们让这两个消费者的消费速度一个快,一个慢

运行结果:

消费者1 收到了 work.queue的消息... :【hello, work, message_1】
消费者2 收到了 work.queue的消息... :【hello, work, message_2】
消费者1 收到了 work.queue的消息... :【hello, work, message_3】
消费者1 收到了 work.queue的消息... :【hello, work, message_5】
消费者1 收到了 work.queue的消息... :【hello, work, message_7】
消费者2 收到了 work.queue的消息... :【hello, work, message_4】
消费者1 收到了 work.queue的消息... :【hello, work, message_9】
消费者1 收到了 work.queue的消息... :【hello, work, message_11】
消费者1 收到了 work.queue的消息... :【hello, work, message_13】
消费者1 收到了 work.queue的消息... :【hello, work, message_15】
消费者2 收到了 work.queue的消息... :【hello, work, message_6】
消费者1 收到了 work.queue的消息... :【hello, work, message_17】
消费者1 收到了 work.queue的消息... :【hello, work, message_19】
消费者1 收到了 work.queue的消息... :【hello, work, message_21】
消费者2 收到了 work.queue的消息... :【hello, work, message_8】
消费者1 收到了 work.queue的消息... :【hello, work, message_23】
消费者1 收到了 work.queue的消息... :【hello, work, message_25】
消费者1 收到了 work.queue的消息... :【hello, work, message_27】
消费者1 收到了 work.queue的消息... :【hello, work, message_29】
消费者2 收到了 work.queue的消息... :【hello, work, message_10】
消费者1 收到了 work.queue的消息... :【hello, work, message_31】
消费者1 收到了 work.queue的消息... :【hello, work, message_33】
消费者1 收到了 work.queue的消息... :【hello, work, message_35】
消费者2 收到了 work.queue的消息... :【hello, work, message_12】
消费者1 收到了 work.queue的消息... :【hello, work, message_37】
消费者1 收到了 work.queue的消息... :【hello, work, message_39】
消费者1 收到了 work.queue的消息... :【hello, work, message_41】
消费者2 收到了 work.queue的消息... :【hello, work, message_14】
消费者1 收到了 work.queue的消息... :【hello, work, message_43】
消费者1 收到了 work.queue的消息... :【hello, work, message_45】
消费者1 收到了 work.queue的消息... :【hello, work, message_47】
消费者1 收到了 work.queue的消息... :【hello, work, message_49】
消费者2 收到了 work.queue的消息... :【hello, work, message_16】
消费者2 收到了 work.queue的消息... :【hello, work, message_18】
消费者2 收到了 work.queue的消息... :【hello, work, message_20】
消费者2 收到了 work.queue的消息... :【hello, work, message_22】
消费者2 收到了 work.queue的消息... :【hello, work, message_24】
消费者2 收到了 work.queue的消息... :【hello, work, message_26】
消费者2 收到了 work.queue的消息... :【hello, work, message_28】
消费者2 收到了 work.queue的消息... :【hello, work, message_30】
消费者2 收到了 work.queue的消息... :【hello, work, message_32】
消费者2 收到了 work.queue的消息... :【hello, work, message_34】
消费者2 收到了 work.queue的消息... :【hello, work, message_36】
消费者2 收到了 work.queue的消息... :【hello, work, message_38】
消费者2 收到了 work.queue的消息... :【hello, work, message_40】
消费者2 收到了 work.queue的消息... :【hello, work, message_42】
消费者2 收到了 work.queue的消息... :【hello, work, message_44】
消费者2 收到了 work.queue的消息... :【hello, work, message_46】
消费者2 收到了 work.queue的消息... :【hello, work, message_48】
消费者2 收到了 work.queue的消息... :【hello, work, message_50】

③观察上述现象:无论两个消费者的消费速度一致,还是不一致,最终二者消费的消息数量都是25条(平分,一人从队列取一半)。

3、为何会出现上述问题?

        rabbitMQ的队列,默认轮询给两个消费者分配消息,而不管消费者的消费速度。该问题的关键是消费者手里还能存储消息,即消费不完的可以存下来,慢慢消费。这就导致了两个消费者平分消息的现象。

        类比:一个大人,一个小孩,一起吃苹果。苹果摊老板不管这两个人吃苹果的速度,只是轮流给两个人发苹果,并且大人和小孩是可以存储还没消费完的苹果,最终导致一共50个苹果,一人发了25个。即:小孩虽然吃得慢,但是兜里能揣啊,于是堆积在手里,一点一点吃。最终小孩还是能分到一半的苹果。

       

4、如何解决上述问题?

        解决方案:消费者消息推送限制

        说白了就是,你吃苹果吃得慢是吧,那我不让你存苹果了,而是让你吃完手里的一个,再拿一个。

         根据上述配置,限制了消费者手里只能留一个消息,即:不让消费者再堆积还没消费的消息了。

        类比:此时苹果摊老板,仍然是轮流给两人发苹果,只不过现在多了一条规矩:手里苹果还没吃完的人,就不给他发苹果了,吃完手里那个苹果的人才能再拿一个苹果。这样就限制了小孩堆积苹果的现象。也就解决了上述问题。

5、根据上述的思路,解决该问题

改进问题后,运行代码:

消费者1 收到了 work.queue的消息... :【hello, work, message_1】
消费者2 收到了 work.queue的消息... :【hello, work, message_2】
消费者1 收到了 work.queue的消息... :【hello, work, message_3】
消费者1 收到了 work.queue的消息... :【hello, work, message_4】
消费者1 收到了 work.queue的消息... :【hello, work, message_5】
消费者1 收到了 work.queue的消息... :【hello, work, message_6】
消费者1 收到了 work.queue的消息... :【hello, work, message_7】
消费者1 收到了 work.queue的消息... :【hello, work, message_8】
消费者1 收到了 work.queue的消息... :【hello, work, message_9】
消费者2 收到了 work.queue的消息... :【hello, work, message_10】
消费者1 收到了 work.queue的消息... :【hello, work, message_11】
消费者1 收到了 work.queue的消息... :【hello, work, message_12】
消费者1 收到了 work.queue的消息... :【hello, work, message_13】
消费者1 收到了 work.queue的消息... :【hello, work, message_14】
消费者1 收到了 work.queue的消息... :【hello, work, message_15】
消费者1 收到了 work.queue的消息... :【hello, work, message_16】
消费者1 收到了 work.queue的消息... :【hello, work, message_17】
消费者2 收到了 work.queue的消息... :【hello, work, message_18】
消费者1 收到了 work.queue的消息... :【hello, work, message_19】
消费者1 收到了 work.queue的消息... :【hello, work, message_20】
消费者1 收到了 work.queue的消息... :【hello, work, message_21】
消费者1 收到了 work.queue的消息... :【hello, work, message_22】
消费者1 收到了 work.queue的消息... :【hello, work, message_23】
消费者1 收到了 work.queue的消息... :【hello, work, message_24】
消费者1 收到了 work.queue的消息... :【hello, work, message_25】
消费者2 收到了 work.queue的消息... :【hello, work, message_26】
消费者1 收到了 work.queue的消息... :【hello, work, message_27】
消费者1 收到了 work.queue的消息... :【hello, work, message_28】
消费者1 收到了 work.queue的消息... :【hello, work, message_29】
消费者1 收到了 work.queue的消息... :【hello, work, message_30】
消费者1 收到了 work.queue的消息... :【hello, work, message_31】
消费者1 收到了 work.queue的消息... :【hello, work, message_32】
消费者1 收到了 work.queue的消息... :【hello, work, message_33】
消费者2 收到了 work.queue的消息... :【hello, work, message_34】
消费者1 收到了 work.queue的消息... :【hello, work, message_35】
消费者1 收到了 work.queue的消息... :【hello, work, message_36】
消费者1 收到了 work.queue的消息... :【hello, work, message_37】
消费者1 收到了 work.queue的消息... :【hello, work, message_38】
消费者1 收到了 work.queue的消息... :【hello, work, message_39】
消费者1 收到了 work.queue的消息... :【hello, work, message_40】
消费者1 收到了 work.queue的消息... :【hello, work, message_41】
消费者2 收到了 work.queue的消息... :【hello, work, message_42】
消费者1 收到了 work.queue的消息... :【hello, work, message_43】
消费者1 收到了 work.queue的消息... :【hello, work, message_44】
消费者1 收到了 work.queue的消息... :【hello, work, message_45】
消费者1 收到了 work.queue的消息... :【hello, work, message_46】
消费者1 收到了 work.queue的消息... :【hello, work, message_47】
消费者1 收到了 work.queue的消息... :【hello, work, message_48】
消费者1 收到了 work.queue的消息... :【hello, work, message_49】
消费者2 收到了 work.queue的消息... :【hello, work, message_50】

可见此时显然不是平分消息,而是能者多劳。

消费者1消费速度快,因此消费了43条消息;

消费者2消费速度慢,因此消费了7条消息。

以上就解决了 忽略消费速度而无脑平分消息的问题。

二、总结

1、知识总结

2、面试题:如何避免消息堆积问题?

①给队列上绑定多个消费者(work模型),从而提高消费速度

②优化代码,使代码执行速度变快,消费速度也就变快了

③rabbitMQ的默认规则:队列中的同一条消息,只能被一个消费者消费。即:不会出现两个消费者消费同一条消息的现象,从而提高消费速度。

④通过设置prefetch,来控制消费者手里最多有1条消息,不允许堆积消息,实现能者多劳。(最重要的一点)

以上就是work模型的全部详细内容,想了解更多的RabbitMQ知识,请关注本博主~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/61792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的数据结构系统设计与实现(源码+定制+开发)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

100.【C语言】数据结构之二叉树的堆实现(顺序结构) 1

目录 1.顺序结构 2.示意图 ​编辑 从物理结构还原为逻辑结构的方法 3.父子节点编号的规律 4.顺序存储的前提条件 5.堆的简介 堆的定义 堆的两个重要性质 小根堆和大根堆 6.堆的插入 7.堆的实现及操作堆的函数 堆的结构体定义 堆初始化函数HeapInit 堆插入元素函…

支持多种快充协议和支持多种功能的诱骗取电协议芯片

汇铭达XSP15是一款应用于手持电动工具、智能家居、显示器、音箱等充电方案的大功率快充协议芯片,支持最大功率100W给设备快速充电,大大缩短了充电时间。芯片支持通过UART串口发送电压/电流消息供其它芯片读取。支持自动识别连接的是电脑或是充电器。支持…

Three.js 相机控制器Controls

在 3D 场景中,摄像机的控制尤为重要,因为它决定了用户如何观察和与场景互动。Three.js 提供了多种相机控制器,最常用的有 OrbitControls、TrackballControls、FlyControls 和 FirstPersonControls。OrbitControls 适合用于查看和检查 3D 模型…

CMake笔记:install(TARGETS target,...)无法安装的Debug/lib下

1. 问题描述 按如下CMake代码,无法将lib文件安装到Debug/lib或Release/lib目录下,始终安装在CMAKE_INSTALL_PREFIX/lib下。 install(TARGETS targetCONFIGURATIONS DebugLIBRARY DESTINATION Debug/lib) install(TARGETS targetCONFIGURATIONS Release…

docker安装使用Elasticsearch,解决启动后无法访问9200问题

1.docker安装、启动es docker pull elasticsearch:8.13.0docker images启动容器 docker run -d -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS"-Xms256m -Xmx256m" --name es01 8ebd258614f1-d 后台运行-p 9200:9200 -p 9300:9300 开放与主机映射端口-e ES_JAVA_OPTS…

java-排序算法汇总

排序算法: 冒泡排序(Bubble Sort) 选择排序(Selection Sort) 插入排序(Insertion Sort) 快速排序(Quick Sort) 归并排序(Merge Sort) 堆排序&…

【笔记】自动驾驶预测与决策规划_Part7_数据驱动的预测方法

文章目录 0. 前言1. 多模态传感器的编码方式1.1 栅格化表示1.2 向量化表示 Vectornet1.3 基于点云或者多模态输入的预测1.4 基于Transformer的方法 2. 网络输出的表达形式2.1 多模态轨迹回归2.2 轨迹分类2.3 轨迹回归轨迹分类2.4 目标点预测 3.场景级别的预测和决策3.1 论文&am…

Tortoise ORM

官方文档:Tortoise ORM - Tortoise ORM v0.22.0 Documentation 简介 Tortoise ORM:异步,API和Django ORM 大多类似集成Pydantic;多用于asgi starlette / sanic / FastAPI...Sqlalchemy:支持异步,Flask / …

【大数据学习 | Spark-Core】关于distinct算子

只有shuffle类的算子能够修改分区数量,这些算子不仅仅存在自己的功能,比如分组算子groupBy,它的功能是分组但是却可以修改分区。 而这里我们要讲的distinct算子也是一个shuffle类的算子。即可以修改分区。 scala> val arr Array(1,1,2,…

java基础概念36:正则表达式1

一、正则表达式的作用 作用一:校验字符串是否满足规则;作用二:在一段文本中查找满足要求的内容。——爬虫 二、正则表达式 2-1、字符类 示例: public static void main(String[] args) {System.out.println("a".matc…

oracle的静态注册和动态注册

oracle的静态注册和动态注册 静态注册: 静态注册 : 指将实例的相关信息手动告知 listener 侦 听 器 , 可以使用netmgr,netca,oem 以及直接 vi listener.ora 文件来实现静态注册,在动态注册不稳定时使用,特点是:稳定&…

html+js实现图片的放大缩小等比缩放翻转,自动播放切换,顺逆时针旋转

效果图&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>图片预览</title><sty…

Selenium+Java(19):使用IDEA的Selenium插件辅助超快速编写Pages

前言 或是惊叹于Selenium对于IDEA的支持已经达到了这样的地步,又或是由于这个好用的小工具的入口就在那里,它已经陪伴了我这么久,而我这么久的时间却都没有发现它。在突然发现这个功能的一瞬间,真的是喜悦感爆棚,于是赶快写下了这篇文章。希望可以帮助到其他同样在做UI自动…

知识付费系统-直播+讲师入驻+课程售卖+商城系统-v2.1.9版本搭建以及资源分享下载+附带完整安装步骤

知识付费系统-直播讲师入驻课程售卖商城系统-v2.1.9版本搭建以及资源分享下载 这是一款很棒&#xff0c;功能很强大的知识付费系统。 源码下载本帖已经绑定&#xff0c;可直接去下载。 1&#xff0c;源码上传 宝塔一键安装后&#xff0c;添加网站上传源码&#xff0c; 2&…

栈的应用,力扣394.字符串解码力扣946.验证栈序列力扣429.N叉树的层序遍历力扣103.二叉树的锯齿形层序遍历

目录 力扣394.字符串解码 力扣946.验证栈序列 力扣429.N叉树的层序遍历 力扣103.二叉树的锯齿形层序遍历 力扣394.字符串解码 看见括号&#xff0c;由内而外&#xff0c;转向用栈解决。使用两个栈处理&#xff0c;一个用String,一个用Integer 遇到数字:提取数字放入到数字栈…

408代码类复习--图类

图类 Author&#xff1a;Joanh_Lan Personal Blog Links&#xff1a;Joanh_LanのCSDN博客 备注&#xff1a; 个人复习版本 不保证完全正确&#xff0c;理性参考&#xff08;不背锅i哦&#xff09; &#xff08;&#xff1a;&#xff08;&#xff1a;&#xff08;&#xff…

Maven的安装——给Idea配置Maven

一、什么是Maven? Maven是一个开源的项目管理工具&#xff0c;它主要用于Java项目的构建、依赖管理和项目生命周期管理。 二、准备环境 maven安装之前&#xff0c;我们要先安装jdk&#xff0c;确保你已经安装了jdk环境。可以通过【win】【r】打开任务管理器&#xff0c;输入…

linux 常用命令指南(存储分区、存储挂载、docker迁移)

前言&#xff1a;由于目前机器存储空间不够&#xff0c;所以‘斥巨资’加了一块2T的机械硬盘&#xff0c;下面是对linux扩容的一系列操作&#xff0c;包含了磁盘空间的创建、删除&#xff1b;存储挂载&#xff1b;docker迁移&#xff1b;anaconda3迁移等。 一、存储分区 1.1 …

OpenCvSharp Demo 饱和度、明度、对比度、锐化、阴影、高光、色温实现滤镜效果

目录 效果 风景-天空滤镜 人像—酷感冷艳滤镜 美食—鲜美滤镜 美食—巧克力滤镜 项目 代码 参考 下载 效果 风景-天空滤镜 人像—酷感冷艳滤镜 美食—鲜美滤镜 美食—巧克力滤镜 项目 代码 using OpenCvSharp; using System; using System.Diagnostics; using Syst…