SpringBoot实现RabbitMQ的WorkQueue(SpringAMQP 实现WorkQueue)

简介: SpringBoot实现RabbitMQ的WorkQueue(SpringAMQP 实现WorkQueue)

1. 前言


上一篇文章,实现了用 SpringBoot实现RabbitMQ的简单队列, 篇文章 操作 用SpringBoot实现RabbitMQ的WorkQueue(SpringAMQP 实现WorkQueue)


Work queues,也被称为(Task queues),任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息。

当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。

此时就可以使用 work 模型,多个消费者共同处理消息处理,速度就能大大提高了。

注意:不一定是两个消费者。


2. 思路


代码实现思路:

1.在 publisher 服务中定义测试方法,产生50条消息(每隔20ms发送一条),发送到 test2024.simple.queue

2.在 consumer 服务中定义两个消息监听者,都监听simple.queue队列

3.消费者1处理50条消息(每隔20ms处理一条),消费者2处理50条消息(每隔100ms处理一条)


3. 消息发送


发送消息前先把 服务接收 的服务停止调.


循环 50 次, 每次休息 20 ms , 发送消息到指定队列

@Test
public void test01() throws InterruptedException {
  //  声明队列名称
   String queueName = "test2024.simple.queue";
   String message = "work_";
   for (int i = 1; i <= 50; i++) {
       // 发送消息
       rabbitTemplate.convertAndSend(queueName, message + i);
       Thread.sleep(20);
   }
}

发送完消息后, 我们看到消息整整齐齐的在 队列里躺着.


4. 消息接收


来连个监听器监听指定的队列, 但是两个监听队列的消费时间不一样.

@Component
public class SpringRabbitListener {

    //  监听指定队列,Spring只要接收到该队列的消息就会接收消息
    @RabbitListener(queues = "test2024.simple.queue")
    public void rabbitListener1(String message){
        System.out.println("1号接收器-接收到消息:" + message);;
    }

    //  监听指定队列,Spring只要接收到该队列的消息就会接收消息
    @RabbitListener(queues = "test2024.simple.queue")
    public void rabbitListener2(String message){
        System.out.println("2号接收器-接收到消息:" + message);;
    }

}

此时启动消费者服务,然后再启动发送消息.

可以看到 1 号接收器很快消费了 25 条, 然后 2 号接收器缓慢的完成自己的… 1 号接收器没有给 2 号接收器帮忙. 那么咋生产环境中 ,就会造成服务闲置的情况下不能及时消费消息.


说明:阐述上述原因是因为队列平均分配给每个消费者,即使当前消费者没有消费完,队列也会将消息分配给消费者。然后消费者一个一个消息消费,即使消费很快的消费者,消费完毕,而消费很慢的消费者一直在消费。这样很不合理。应该是哪个消费者消费快应该多消费。哪个消费者消费慢应该少消费。


4.1 能者多劳

在 Spring 中有一个简单的配置叫预取 prefetch,可以解决这个问题。我们修改 consumer 服务的 application.yml 文件,添加配置:

 listener:
      simple:
        prefetch: 1   # 消费者每次最多只能预取一条消息,当消费完这条消息后,才能获取下一个消息,这样做的好处是消费能力强的消费者,处理的消息就会更多===》能者多劳

做了如上配置后,启动消费者服务,再次发送消息:

我们看到消费能力强的1号接收器完成了更多的工作,这样就达到了能者多劳.


总结


Work模型的使用:

  • 多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
  • 通过设置prefetch来控制消费者预取的消息数量
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
18天前
|
消息中间件 Java 网络架构
|
13天前
|
消息中间件 Java 测试技术
消息中间件RabbitMQ---SpringBoot整合RabbitMQ【三】
这篇文章是关于如何在SpringBoot应用中整合RabbitMQ的消息中间件。内容包括了在SpringBoot项目中添加RabbitMQ的依赖、配置文件设置、启动类注解,以及如何通过单元测试来创建交换器、队列、绑定,并发送和接收消息。文章还介绍了如何配置消息转换器以支持对象的序列化和反序列化,以及如何使用注解`@RabbitListener`来接收消息。
消息中间件RabbitMQ---SpringBoot整合RabbitMQ【三】
|
17天前
|
网络协议 Java 物联网
MQTT(EMQX) - SpringBoot 整合MQTT 连接池 Demo - 附源代码 + 在线客服聊天架构图
MQTT(EMQX) - SpringBoot 整合MQTT 连接池 Demo - 附源代码 + 在线客服聊天架构图
70 2
|
18天前
|
消息中间件 Java Maven
|
2月前
|
消息中间件 Java 测试技术
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
124 1
|
2月前
|
消息中间件 Java 数据安全/隐私保护
Spring Boot与RabbitMQ的集成
Spring Boot与RabbitMQ的集成
|
2月前
|
消息中间件 Java RocketMQ
Spring Boot与RocketMQ的集成
Spring Boot与RocketMQ的集成
|
2月前
|
消息中间件 Java Spring
实现Spring Boot与RabbitMQ消息中间件的无缝集成
实现Spring Boot与RabbitMQ消息中间件的无缝集成
|
2月前
|
消息中间件 C语言 RocketMQ
消息队列 MQ操作报错合集之出现"Connection reset by peer"的错误,该如何处理
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
下一篇
云函数