1. RabbitMQ 持久化机制
RabbitMQ 的持久化分为队列持久化、消息持久化和交换器持久化。 不管是持久化的消息还是非持久化的消息都可以被写入到磁盘。区别在于重启之后数据还在不在。
- 持久化
- 非持久化
1. 队列持久化
- 队列的持久化是在定义队列时的 durable 参数来实现的,durable 为 true 时,队列才会持久化。
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 第二个参数设置为 true,则 durable=true
channel.queueDeclare("queue1", true, false, false, null);
- 持久化的队列在管理界面可以看到有个“D”的标识。
2. 消息持久化
- 消息持久化通过消息的属性 deliveryMode 来设置是否持久化,在发送消息时通过 basicPublish 的参数传入。
// 通过传入 MessageProperties.PERSISTENT_TEXT_PLAIN 就可以实现消息持久化。
channel.basicPublish("", "queue1", MessageProperties.PERSISTENT_TEXT_PLAIN, "persistent_test_message".getBytes());
3. 交换器持久化
- 同队列一样,交换器也需要在定义时设置持久化标识,否则在 Broker 重启后数据将丢失。
// durable 为 true 则开启持久化
Exchange.DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable) throws IOException;
2. RabbitMQ 内存控制
- 当内存使用超过配置的阀值,RabbitMQ 会暂停阻塞客户端的连接,并停止接收从客户端发来的消息,以此避免服务崩溃,客户端与服务端的心跳检测也会失效。
rabbitmqctl set_vm_memory_hight_watermark <fraction>
RabbitMQ 内存换页
3. RabbitMQ 磁盘控制
1. RabbitMQ 磁盘告警
- 当磁盘剩余空间低于确定的阀值时,RabbitMQ 同样会阻塞生产者,这样可以避免因非持久化的消息持续换页而耗尽磁盘空间导致服务崩溃。
- 默认情况下,磁盘阀值为 50MB,表示当磁盘空间低于 50MB 时会阻塞生产者并停止内存中消息的换页动作。
- 这个阀值的设置可以减小,但不能完全消除磁盘耗尽而导致崩溃的可能性。比如在两次磁盘空间检测期间内,磁盘空间从大于 50MB 被耗尽到 0MB。
- 一个相对谨慎的做法是将磁盘阀值设置为与操作系统所显示的内存大小一致。