欢迎来到“雪碧聊技术”CSDN博客!
在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将不断探索Java的深邃世界,分享最新的技术动态、实战经验以及项目心得。
让我们一同在Java的广阔天地中遨游,携手提升技术能力,共创美好未来!感谢您的关注与支持,期待在“雪碧聊技术”与您共同成长!
目录
③观察上述现象:无论两个消费者的消费速度一致,还是不一致,最终二者消费的消息数量都是25条(平分,一人从队列取一半)。
③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){//消费者1
System.out.println("消费者1 收到了 work.queue的消息... :【" + msg + "】");
}
@RabbitListener(queues = "work.queue")
public void listenWorkQueue2(String msg){//消费者2
System.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知识,请关注本博主~~