更新时间:2023-02-06 GMT+08:00

惰性队列

使用场景

默认情况下,RabbitMQ生产者生产的消息存储在内存中,当需要释放内存时,会将内存中的消息换页至磁盘中。换页操作会消耗较长的时间,且换页过程中队列无法处理消息。

如果生产速度过快(例如执行批处理任务),或者消费者由于各种原因(例如消费者下线、宕机)长时间内无法消费消息,导致消息大量堆积,使得内存使用率过高,换页频繁,可能会影响其他队列的消息收发。这种场景下,建议您启用惰性队列。

惰性队列(Lazy Queue)会尽可能的将消息存入磁盘中,在消费者消费到相应的消息时才会被加载到内存中,这样可以减少内存的消耗,但是会增加I/O的使用,影响单个队列的吞吐量。惰性队列的一个重要的设计目标是能够支持更长的队列,即支持更多的消息存储/消息堆积。

在以下情况下,推荐使用惰性队列:

  • 队列可能会产生消息堆积
  • 队列对性能(吞吐量)的要求不是非常高,例如TPS 1万以下的场景
  • 希望队列有稳定的生产消费性能,不受内存影响而波动

处于以下情况时,无需使用惰性队列:

  • RabbitMQ需要高性能的场景
  • 队列总是很短(即队列中没有消息堆积)
  • 设置了最大长度策略

更多关于惰性队列的说明,请参考Lazy Queues

设置惰性队列

队列具备两种模式:default和lazy,默认模式为default。lazy模式即为惰性队列的模式,可以通过调用channel.queueDeclare方法的时候在参数中设置,也可以通过Policy的方式设置。如果一个队列同时使用这两种方式设置的话,Policy的方式具备更高的优先级。

  • 以下示例演示在Java客户端通过调用channel.queueDeclare设置惰性队列。
    Map<String, Object> args = new HashMap<String, Object>();
    args.put("x-queue-mode", "lazy");
    channel.queueDeclare("myqueue", false, false, false, args);
  • 以下示例演示在RabbitMQ WebUI页面通过Policy的方式设置惰性队列。
    图1 通过Policy的方式设置惰性队列