RabbitMQ惰性队列

消息堆积问题

  • 当生产者发送消息的速度,超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。导致之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。

解决方案

  • 解决消息堆积的两种思路
    • 增加更多消费者,提高消费速度。也就是work queue模式
    • 扩大队列容积,提高堆积上限
  • 上面2种方式,都需要加机器、加内存,需要花钱要成本,那么可不可以不花钱,利用起我们的磁盘空间呢?
  • 注意:提升队列容积,把消息保存在内存中,消息一多,内存很容易就满了,这显然是不行的,我们可以考虑存到磁盘中,存磁盘的缺点就是慢

惰性队列

  • 从RabbitMQ的3.6.0版本开始,就增加了Lazy Queues的概念,也就是惰性队列
  • 惰性队列有以下特征
    • 接收到消息后,直接存入磁盘而非内存
    • 消费者要消费消息时,才会从磁盘中读取并加载到内存
    • 支持数百万条的消息存储

声明惰性队列

命令行的方式

rabbitmqctl set_policy Lazy "^simple.queue$" '{"queue-mode":"lazy"}' --apply-to queues
  • 命令解读
    • rabbitmqctl :RabbitMQ的命令行工具
    • set_policy :添加一个策略
    • Lazy :策略名称,可以自定义
    • "^lazy-queue$" :用正则表达式匹配队列的名字
    • '{"queue-mode":"lazy"}' :设置队列模式为lazy模式
    • --apply-to queues:策略的作用对象,是所有的队列

Java代码的方式

  • 方案一:通过@Bean方式声明队列,配置lazy属性
@Bean
public Queue lazyQueue() {
    return QueueBuilder
        .durable("lazy.queue")
        // 开启x-queue-mode,并设置为lazy
        .lazy()
        .builder();
}
  • 方案二:通过@RabbitListener,配置x-queue-mode参数,并指明参数值为lazy
@RabbitListener(queueToDeclare = @Queue(
    name = "lazy.queue",
    durable = "true",
    arguments = @Argument(name="x-queue-mode",value ="lazy" )
))
public void listenLazyQueue(String msg){
    log.info("接收到 lazy.queue的消息:{}", msg);
}

总结

  • 消息堆积问题的解决方案?
    • 队列上绑定多个消费者,提高消费速度
    • 使用惰性队列,可以在mq中保存更多消息
  • 惰性队列的优点有哪些?
    • 基于磁盘存储,消息上限高
    • 没有间歇性的page-out(内存到硬盘),性能比较稳定
  • 惰性队列的缺点有哪些?
    • 基于磁盘存储,消息时效性会降低
    • 性能受限于磁盘的IO
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容