RabbitMQ消息堆积问题及惰性队列

一,消息堆积

1,消费者堆积问题

当生产者生产消息的速度超过了消费者处理消息的速度,就会导致消息在队列中进行堆积,一定时间后会造成队列达到存储的上限,那么最开始进入队列的消息可能变成死信,会被丢弃(有关死信以及死信消息的处理问题的详细介绍可以看我的另一篇博客:RabbitMQ死信交换机、TTL及延迟队列_蜡笔小心眼子!的博客-CSDN博客)。

2,消息堆积的解决方案

解决消息堆积的方案一般是三种:

  1. 增加更多的消费者,多个消费者处于竞争的关系进行消息的消费(类似于RabbitMQ的工作模式);
  2. 对于单个消费者来说,可以采用线程池的方式进行消息的处理,消费者每拿到一个消息的时候就会创建一个线程来处理该消息;
  3. 扩大队列容积,提高堆积的上限。

二,惰性队列

1,惰性队列的特征

惰性队列(Lazy Queus),一般有如下三个特征:

  1. 接收到消息后直接存入磁盘而非内存;
  2. 消费者要消费消息时才会从磁盘中读取并加载到内存;
  3. 支持数百万条的消息存储。

2,设置惰性队列

2.1 将已经声明的队列设置成惰性队列

设置一个队列为惰性队列,只需要在声明队列时,指定x-queue-mode属性为lazy即可,可以通过命令行将一个运行中的队列修改为惰性队列:

java 复制代码
rabbitmqctl set_policy Lazy "^lazy-queue$" '{"queue-mode":"lazy"}' --apply-to queues 

2.2 声明队列时将队列设置成惰性队列

@Bean方式:

java 复制代码
    @Bean
    public Queue lazyQueue() {
        return QueueBuilder.durable("lazy.queue")
                .lazy()//开启x-queue-mode属性为lazy
                .build();
    }

注解方式:

java 复制代码
 @RabbitListener(queuesToDeclare = @Queue(
            name = "lazy.queue",
            durable = "true",
            //开启x-queue-mode属性为lazy
            arguments = @Argument(name = "x-queue-mode", value = "lazy")
    ))
    public void listenLazyQueue(String msg) {
        log.info("接收到 lazy.queue的消息:{}", msg);
    }

3,惰性队列的优缺点

3.1 优点

  1. 基于磁盘存储,消息上限高;
  2. 没有间歇性的page-out,性能比较稳定。

3.2 缺点

  1. 基于磁盘存储,消息时效性会降低;
  2. 性能受限于磁盘的IO。
相关推荐
兮动人1 小时前
Eureka注册中心通用写法和配置
java·云原生·eureka
爱编程的小白L3 小时前
基于springboot志愿服务管理系统设计与实现(附源码)
java·spring boot·后端
聪明的笨猪猪5 小时前
Java Redis “持久化”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
聪明的笨猪猪5 小时前
Java Redis “核心基础”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
奋斗的小monkey7 小时前
Spring Boot 3.x核心特性与性能优化实战
java·spring boot·微服务·性能优化·响应式编程
程序猿DD8 小时前
将 GPU 级性能带到企业级 Java:CUDA 集成实用指南
java·架构
一成码农9 小时前
JavaSE面向对象(上)
java
qq_574656259 小时前
java-代码随想录第66天|Floyd 算法、A * 算法精讲 (A star算法)
java·算法·leetcode·图论
我是好小孩9 小时前
【Android】六大设计原则
android·java·运维·服务器·设计模式