Lazy Queue
惰性队列会尽可能的将消息存入磁盘中,在消费者消费到相应的消息时才会被加载到内存中。
优点
- 它可以存储更多消息支持更长队列因为消息在硬盘中。
- 惰性队列可以避免消息堆积导致的内存崩溃。
缺点
- 需要i/o 增加磁盘i/o。
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-queue-mode", "lazy");
channel.queueDeclare("myqueue", false, false, false, args);
存储机制
- 持久化消息会被写入到磁盘,如果内存够也会写入到内存以提高性能。当内存不够用会从内存中清除。
- 非持久化消息保存在内存中,在内存不够用时会被移到磁盘中,以节省内存空间。
- 这两种类型的消息的落盘处理都在 RabbitMQ 的"持久层"中 完成。
持久层是一个逻辑上的概念,实际包含两个部分 :
- 队列索引 rabbit_queue_index :负责维护消息的存储地点、是否己被交付给消费者、是否己被消费者 ack等。
- 消息存储 rabbit_msg_store: 以键值对的形式存储消息,它被所有队列共享, 在每个节点中有且只有一个。
- queue_index_embed_msgs_below 默认大小为 4096通过配置这个参数可以让消息存在索引中还是存储中
内存警告
Rabbit MQ服务器在启动和执行 rabbitmqctl set_vm_memory_high_watermark fraction 的时候会检测机器上的RAM大小,默认情况下,Rabbit MQ使用内存超过40%的时候,会发出内存警告,阻塞所有发布消息的连接。
内存阈值通过 rabbitmq.config 配置
比例:[{rabbit, [{vm_memory_high_watermark, 0.4}]}]
绝对值:[{rabbit, [{vm_memory_high_watermark, {absolute, 1073741824}}]}
磁盘警告
磁盘可用空间下降到配置值(默认为50M)以下会触发一个警告,所有生产者会被阻塞从而导致写操作失败,瞬时进来的消息,也会被写到磁盘,继续占用阈值下磁盘空间,如果阈值设置过低会导致瞬时消息写满整个磁盘,导致RabbitMQ崩溃。(正常情况每隔10秒检查一次阈值,当快接近阈值时每秒检查10次)。
[{rabbit, [{disk_free_limit, 1000000000}]}].
如果一个 Broker 节点的内存或者磁盘受限,都会引起整个集群中所有的 Connection 被阻塞。
流控
rabbitMQ的流控可以分为两种:
- 一种是单个链接上的流控:Per-Connection Flow Control
当生产者发布消息太快,消费者消费速度低于生产速度,RabbitMQ会降低生产者的速度,无需配置。流控的Connection可以在rabbitmqctl、管理UI和HTTP API响应中显示flow状态。被流控Connection发布消息时每秒要经过多次阻塞和解除阻塞以降低写入速度。
- 一种是全局流控:
- Memory-Based Flow Control 全局内存控制
- Disk-Based Flow Control 全局磁盘控制