工作队列模式结构图:

这种模式非常适合多个工人等待任务到来的场景。任务有多个,一个一个丢进消息队列,工人也有很多个,就可以将这些任务分配个各个工人,让他们各自负责一些任务,并且做的快的工人还可以多完成一些(能者多劳)。

要实现这种模式,只需要创建多个监听器即可。

先监听再发消息

这里先介绍先监听再发送消息的情况。

  1. 定义配置类。

    1. import org.springframework.amqp.core.Binding;
    2. import org.springframework.amqp.core.BindingBuilder;
    3. import org.springframework.amqp.core.Exchange;
    4. import org.springframework.amqp.core.ExchangeBuilder;
    5. import org.springframework.amqp.core.Queue;
    6. import org.springframework.amqp.core.QueueBuilder;
    7. import org.springframework.beans.factory.annotation.Qualifier;
    8. import org.springframework.context.annotation.Bean;
    9. import org.springframework.context.annotation.Configuration;
    10. /**
    11. * RabbitMQ配置类
    12. *
    13. * @author CodeSail
    14. */
    15. @Configuration
    16. public class RabbitMqConfig {
    17. /**
    18. * 定义交换机,可以很多个
    19. * @return 交换机对象
    20. */
    21. @Bean("directExchange")
    22. public Exchange exchange(){
    23. return ExchangeBuilder.directExchange("amq.direct").build();
    24. }
    25. /**
    26. * 定义消息队列
    27. * @return 消息队列对象
    28. */
    29. @Bean("testQueue")
    30. public Queue queue(){
    31. return QueueBuilder
    32. // 非持久化类型
    33. .nonDurable("test_springboot")
    34. .build();
    35. }
    36. /**
    37. * 定义绑定关系
    38. * @return 绑定关系
    39. */
    40. @Bean
    41. public Binding binding(@Qualifier("directExchange") Exchange exchange,
    42. @Qualifier("testQueue") Queue queue){
    43. // 将定义的交换机和队列进行绑定
    44. return BindingBuilder
    45. // 绑定队列
    46. .bind(queue)
    47. // 到交换机
    48. .to(exchange)
    49. // 使用自定义的routingKey
    50. .with("test_springboot_key")
    51. // 不设置参数
    52. .noargs();
    53. }
    54. }
  2. 创建两个监听器,监听同一队列。

    1. import org.springframework.amqp.rabbit.annotation.RabbitListener;
    2. import org.springframework.stereotype.Component;
    3. /**
    4. * 工作队列监听器
    5. *
    6. * @author 廖航
    7. */
    8. @Component
    9. public class WorkListener {
    10. @RabbitListener(queues = "test_springboot")
    11. public void receiver1(String message) {
    12. System.out.println("1号监听器:" + message);
    13. }
    14. @RabbitListener(queues = "test_springboot")
    15. public void receiver2(String message) {
    16. System.out.println("2号监听器:" + message);
    17. }
    18. }
  3. 定义生产者。

    1. import org.junit.jupiter.api.Test;
    2. import org.springframework.amqp.rabbit.core.RabbitTemplate;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. import java.util.concurrent.TimeUnit;
    6. @SpringBootTest
    7. class RabbitMqSpringBootTests {
    8. /**
    9. * RabbitTemplate封装了大量的RabbitMQ操作,已经由Starter提供,因此直接注入使用即可
    10. */
    11. @Autowired
    12. private RabbitTemplate rabbitTemplate;
    13. /**
    14. * 生产者
    15. */
    16. @Test
    17. void producer() throws InterruptedException {
    18. for (int i = 0; i < 10; i++) {
    19. TimeUnit.SECONDS.sleep(1);
    20. rabbitTemplate.convertAndSend("amq.direct", "test_springboot_key", "Hello World");
    21. }
    22. }
    23. }
  4. 启动生产者发送消息。

    可以看到,当同一个队列有多个监听器时,默认采用轮询的方式消费消息。

先发消息再监听

前面介绍了先监听再发消息的情况,下面介绍先发消息再监听的情况。

  1. 向队列中发送10条消息。

  2. 启动服务消费消息。

    可以看到,如果是一开始就存在消息,会被一个消费者一次性全部消费,这是因为没有对消费者的Prefetch count(预获取数量,一次性获取消息的最大数量)进行限制。

    默认的Prefetch count为250。

    也就是说如果希望消费者一次只拿一个消息,而不是将所有的消息全部都获取,需要设置Prefetch count。

要对这个数量进行配置,需要在配置类中定义一个自定义的ListenerContainerFactory,可以在这里设置消费者Channel的PrefetchCount的大小。

  1. 配置类中定义ListenerContainerFactory

    1. import org.springframework.amqp.core.Binding;
    2. import org.springframework.amqp.core.BindingBuilder;
    3. import org.springframework.amqp.core.Exchange;
    4. import org.springframework.amqp.core.ExchangeBuilder;
    5. import org.springframework.amqp.core.Queue;
    6. import org.springframework.amqp.core.QueueBuilder;
    7. import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
    8. import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
    9. import org.springframework.beans.factory.annotation.Autowired;
    10. import org.springframework.beans.factory.annotation.Qualifier;
    11. import org.springframework.context.annotation.Bean;
    12. import org.springframework.context.annotation.Configuration;
    13. /**
    14. * RabbitMQ配置类
    15. *
    16. * @author CodeSail
    17. */
    18. @Configuration
    19. public class RabbitMqConfig {
    20. @Autowired
    21. private CachingConnectionFactory connectionFactory;
    22. ...
    23. @Bean(name = "listenerContainer")
    24. public SimpleRabbitListenerContainerFactory listenerContainer(){
    25. SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    26. factory.setConnectionFactory(connectionFactory);
    27. // 将PrefetchCount设定为1表示一次只能取一个
    28. factory.setPrefetchCount(1);
    29. return factory;
    30. }
    31. }
  2. 监听器中指定。

    1. import org.springframework.amqp.rabbit.annotation.RabbitListener;
    2. import org.springframework.stereotype.Component;
    3. /**
    4. * 工作队列监听器
    5. *
    6. * @author 廖航
    7. */
    8. @Component
    9. public class WorkListener {
    10. @RabbitListener(queues = "test_springboot", containerFactory = "listenerContainer")
    11. public void receiver1(String message) {
    12. System.out.println("1号监听器:" + message);
    13. }
    14. @RabbitListener(queues = "test_springboot", containerFactory = "listenerContainer")
    15. public void receiver2(String message) {
    16. System.out.println("2号监听器:" + message);
    17. }
    18. }
  3. 向队列中发送10条消息。

  4. 启动服务消费消息。

    可以看到,两个监听器又实现了轮询消费消息。

    Prefetch count设为了1。

至此,工作队列模式的两种情况就介绍完毕了。


RabbitMQ 06 工作队列模式的更多相关文章

  1. RabbitMQ六种队列模式-工作队列模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列 [本文]RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  2. 【RabbitMQ】工作模式介绍

    一.前言 之前,笔者写过< CentOS 7.2 安装 RabbitMQ> 这篇文章,今天整理一下 RabbitMQ 相关的笔记便于以后复习. 二.模式介绍 在 RabbitMQ 官网上提 ...

  3. RabbitMQ六种队列模式-简单队列模式

    前言 RabbitMQ六种队列模式-简单队列 [本文]RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  4. RabbitMQ六种队列模式-发布订阅模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  5. RabbitMQ六种队列模式-路由模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...

  6. RabbitMQ六种队列模式-主题模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主题模式 [ ...

  7. java面试一日一题:rabbitMQ的工作模式

    问题:请讲下rabbitMQ的工作模式 分析:该问题纯属概念题,需要掌握rabbtiMQ的基础知识,同时该题也是切入MQ的一个引子: 回答要点: 主要从以下几点去考虑, 1.rabbitMQ的基本概念 ...

  8. RabbitMQ之消息模式(下)

    目的: RabbitMQ之消息模式(上):https://www.cnblogs.com/huangting/p/11994539.html 消费端限流 消息的ACK与重回队列 TTL消息 死信队列 ...

  9. 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_9.RabbitMQ研究-工作模式-发布订阅模式-消费者

    消费者需要写两个消费者 定义邮件的类 复制以前的代码到邮件类里面进行修改 最上面 声明队列的名称和交换机的名称 监听修改为email 的队列的名称 手机短信接收端 复制一份email的接收端的代码 改 ...

  10. 【RabbitMQ】六种模式与SpringBoot整合

    添加rabbitmq的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

随机推荐

  1. 【Azure 环境】自动化账号生成的时候怎么生成连接与证书

    问题描述 自动化账号生成的时候怎么生成连接与证书? 什么是自动化? Azure 自动化提供基于云的自动化和配置服务,用于支持 Azure 环境和非 Azure 环境之间的一致管理. Azure 自动化 ...

  2. 【Azure 事件中心】如何查看事件中心的消息中具体报文内容呢?

    问题描述 如何查看事件中心的消息中具体报文内容呢? 问题解答 正常情况是通过 Event Hub 的消费端获取消息进行处理查看,但是没有客户端代码的情况下,也可以通过微软的默认客户端Service B ...

  3. C++函数模板总结:

    //C++提高编程 模板(泛型编程 STL)//模板不可以直接使用 它只是一个框架//模板的通用并不是万能的//语法//template<typename T>//函数模板两种方式//1. ...

  4. 关于Chrome版本太旧的更新问题

    •问题 这两天不知道咋了,Chrome 老是给我提示版本太旧,需要更新. 作为一名资深的强迫症患者,这让我很是不爽. •解决方案 在桌面找到 Chrome 图标,右击选择[属性],在该位置添加如下语句 ...

  5. 机器学习从入门到放弃:卷积神经网络CNN(二)

    一.前言 通过上一篇文章,我们大概了解了卷积是什么,并且分析了为什么卷积能在图像识别上起到巨大的作用.接下来,废话不多话,我们自己尝试动手搭建一个简易的CNN网络. 二.准备工作 在开始的时候,我们首 ...

  6. Zabbix Agent item监控项讲解

    前言 agent与snmp是Zabbix两种重要的监控方式,这一期主要介绍Zabbix Agent item监控项..Zabbix agent分为主动代理.被动代理,配置item类型时,可以选择需要的 ...

  7. Spring整合mybatis使用xml配置事务

    自己准备开始教授Java相关的技术,Spring框架是必须让学生学习的框架之一.里面有一个事务相关的 配置,以前刚学习Spring框架的时候有接触过,只是过了很多年,很多东西都已经淡忘.再来回忆一下 ...

  8. vue2init vue2z

    <template> <div> </div> </template> <script> export default { name: 'b ...

  9. gyroflow.xyz - 视频防抖 支持相机 gopro 不支持手机视频 - 软件推荐

    gyroflow.xyz - 视频防抖 支持相机 gopro 不支持手机视频 - 软件推荐 https://gyroflow.xyz/ https://github.com/gyroflow/gyro ...

  10. 向TreeView添加自定义信息

    可在 Windows 窗体 TreeView 控件中创建派生节点,或在 ListView 控件中创建派生项. 通过派生可添加任何所需字段,以及添加处理这些字段的自定义方法和构造函数. 此功能的用途之一 ...