工作队列模式结构图:

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

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

先监听再发消息

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

  1. 定义配置类。

    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.Exchange;
    import org.springframework.amqp.core.ExchangeBuilder;
    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.core.QueueBuilder;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration; /**
    * RabbitMQ配置类
    *
    * @author CodeSail
    */
    @Configuration
    public class RabbitMqConfig { /**
    * 定义交换机,可以很多个
    * @return 交换机对象
    */
    @Bean("directExchange")
    public Exchange exchange(){
    return ExchangeBuilder.directExchange("amq.direct").build();
    } /**
    * 定义消息队列
    * @return 消息队列对象
    */
    @Bean("testQueue")
    public Queue queue(){
    return QueueBuilder
    // 非持久化类型
    .nonDurable("test_springboot")
    .build();
    } /**
    * 定义绑定关系
    * @return 绑定关系
    */
    @Bean
    public Binding binding(@Qualifier("directExchange") Exchange exchange,
    @Qualifier("testQueue") Queue queue){
    // 将定义的交换机和队列进行绑定
    return BindingBuilder
    // 绑定队列
    .bind(queue)
    // 到交换机
    .to(exchange)
    // 使用自定义的routingKey
    .with("test_springboot_key")
    // 不设置参数
    .noargs();
    }
    }
  2. 创建两个监听器,监听同一队列。

    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component; /**
    * 工作队列监听器
    *
    * @author 廖航
    */
    @Component
    public class WorkListener { @RabbitListener(queues = "test_springboot")
    public void receiver1(String message) {
    System.out.println("1号监听器:" + message);
    } @RabbitListener(queues = "test_springboot")
    public void receiver2(String message) {
    System.out.println("2号监听器:" + message);
    } }
  3. 定义生产者。

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

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

先发消息再监听

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

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

  2. 启动服务消费消息。

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

    默认的Prefetch count为250。

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

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

  1. 配置类中定义ListenerContainerFactory

    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.Exchange;
    import org.springframework.amqp.core.ExchangeBuilder;
    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.core.QueueBuilder;
    import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
    import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration; /**
    * RabbitMQ配置类
    *
    * @author CodeSail
    */
    @Configuration
    public class RabbitMqConfig { @Autowired
    private CachingConnectionFactory connectionFactory; ... @Bean(name = "listenerContainer")
    public SimpleRabbitListenerContainerFactory listenerContainer(){
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    // 将PrefetchCount设定为1表示一次只能取一个
    factory.setPrefetchCount(1);
    return factory;
    }
    }
  2. 监听器中指定。

    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component; /**
    * 工作队列监听器
    *
    * @author 廖航
    */
    @Component
    public class WorkListener { @RabbitListener(queues = "test_springboot", containerFactory = "listenerContainer")
    public void receiver1(String message) {
    System.out.println("1号监听器:" + message);
    } @RabbitListener(queues = "test_springboot", containerFactory = "listenerContainer")
    public void receiver2(String message) {
    System.out.println("2号监听器:" + message);
    } }
  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. AFNetworking整体框架简单整理

    一.AFNetworking整体框架是怎样的 1.UIKit集成模块 UIKit 2.请求序列化 Serialization 3.响应序列化 Serialization 4.会话 NSURLSessi ...

  2. 你不得不知道的 MySQL 优化原理

    目录 MySQL逻辑架构 MySQL查询过程 客户端/服务端通信协议 查询缓存 查询优化 查询执行引擎 返回结果给客户端 总结 性能优化建议 Scheme设计与数据类型优化 创建高性能索引 索引相关的 ...

  3. [Python] 协程学习过程

    开始 ​ 之前一直在做那个rProxy的项目,后来发现,服务端不用协程或者异步编程这样的手段是不行的,最主要的问题就是对于每个http请求都对应一个线程,这个开销非常大.对于一个网页而言,四五十个ht ...

  4. 为什么(++a)+(++a)=14

    目录 概述 验证 反编译大法 Java 测试 概述 今天有学妹问我,下面这个代码为啥结果是14 int a=5; printf("%d\n",(++a)+(++a)); 我一看,第 ...

  5. 2.Canal连接MQ

    1. 配置文件介绍 Canal的启动,是以创建实例(instance)的方式,每个实例都有自己单独的工作环境, 而配置也分成两个部分 canal.properties (系统根配置文件) instan ...

  6. 冲击900亿美元估值!邀约路演、秘密交表的Shein上市有望

    双十一的狂欢刚刚结束,Shein即将赴美上市的消息又在电商圈里投下一枚重磅炸弹. 继被媒体曝光其寻求900亿美金估值后,最新的消息称其已邀请投资人参与路演,且已秘密完成交表.这个神秘的中国独角兽,离敲 ...

  7. Redis单线程为什么如此之快

    一.概述 Redis的高并发和快简单可以归结为一下几点: 1.Redis是基于内存的: 2.Redis是单线程的: 3.Redis使用多路复用技术. 4.高效的数据结构 但具体怎么做的呢,下面来详细看 ...

  8. centos7 开机自动执行脚本

    1.因为在centos7中/etc/rc.d/rc.local的权限被降低了,所以需要赋予其可执行权 chmod +x /etc/rc.d/rc.local 2.赋予脚本可执行权限假设/usr/loc ...

  9. python script 编写摘要(一)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  10. flume采集nginx日志文件数据到Kafka

    flume官网地址http://flume.apache.org/ #下载 wget https://mirrors.bfsu.edu.cn/apache/flume/1.9.0/apache-flu ...