1、持久化机制

rabbitmq的持久化分为队列持久化、消息持久化和交换器持久化。 不管是持久化的消息还是非持久化的消息都可以被写入到磁盘。

持久化消息会同时写入磁盘和内存(加快读取速度),非持久化消息会在内存不够用时,将消息写入磁盘(一般重启之后就没有了)。

RabbitMQ持久化 java rabbitmq持久化到磁盘_中间件

 

RabbitMQ持久化 java rabbitmq持久化到磁盘_中间件_02

 

(1)、队列的持久化是在定义队列时的durable参数来决定的,当durable为true时,才代表队列会持久化。

 

Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//第二个餐胡设置为true,代表队列持久化
channel.queuDeclare("q_1",true,false,false,null);

 

(2)、消息持久化通过消息的deliveryMode来设置,在发送消息是通过basicPublish的参数传入。

//通过传入MessageProperties.PERSISTENT_PLAIN就可以实现消息持久化
channel.basicPublish("","q_1",MessageProperties.PERSISTENT_PLAIN,"persistent_test_message".getBytes());

(3)、交换器也需要在定义的时候设置持久化标志,否则在rabbitmq重启后将丢失。

//durable为true则开启持久化
Exchange.DeclareOk exchangeDeclare(String exchange,String type,boolean durable)throws IOException

~exchange 交换器的名称

~ type 交换器的类型,常见的如 fanout direct topic

~ durable: 设置是否持久 durab 设置为 true 表示持久化, 反之是非持久 。持久化可以将交换器存盘,在服务器重启 的时候不会丢失相关信息。

2、内存控制

(1)、内存告警

当内存使用超过配置的阈值或者磁盘剩余控件低于配置的阈值时,rabbitmq会暂时阻塞客户端的连接,并停止接收从客户端发来的消息,以避免服务崩溃,客户端与服务端的心跳检测也会失败。

当出现内存告警时,可以通过管理命令临时调整内存大小。

rabbitmqctl set_vm_memory_high_watermark <fraction>

fraction为内存阈值,rabbitmq默认是0.4,表示当rabbitmq使用的内存超过总内存的40%时,就会产生告警并阻塞所有生产则连接。
通过此命令修改的阈值在rabbitmq重启之后将会失效,通过修改配置文件的方式设置的阈值才会永久有效,但需要重启服务才会生效。

配置文件:rabbitmq.conf

#相对值,也就是前面的fraction,建议设置在0.4~0.66之间,不要超过0.7
vm_memory_high_watermark.relative=0.4
#绝对值,单位为KB,MB,GB,对应的临时命令是:rabbitmqctl set_vm_memory_high_watermark absolute <value>
#vm_memory_high_watermark.absolute=1GB

(2)、内存换页

在某个broker节点触及内存并阻塞生产者之前,他会尝试将队列内存中的消息换页存储到磁盘以释放内存空间。持久化和非持久化的消息都会被转储到磁盘中,其中持久化的消息本身就在磁盘中有一个备份,所以这里会将持久化的消息从内存中清除掉。

默认情况下,在内存达到内存阈值的50%时会进行换页操作。也就是说,在默认的内存阈值40%的情况下,当内存超过0.4*0.5=0.2时会经行换页动作。

内存换页可以通过在配置文件中设置来进行调整。

vm_memory_high_watermark_paging_ratio=0.75

以上配置将会在rabbitmq内存使用率达到30%(假设内存阈值时0.4)时进行换页动作,并在40%时阻塞生产者。当vm_memory_high_watermark_paging_ratio的值大于1时,相当于禁用了换页功能。

3、磁盘控制

(1)、磁盘告警

当磁盘剩余空间低于设置的阈值时,rabbitmq同样会阻塞生产者,这样可以避免因非持久化的消息持续换页而耗尽磁盘空间导致服务崩溃。

默认情况下,磁盘的阈值是50M,表示当磁盘剩余空间低于50M时,会阻塞生产者并停止内存中消息的换页动作。这个阈值的设置可以减小,但不能完全消除因磁盘耗尽而导致崩溃的可能性。比如在两次磁盘空间检测期间内,磁盘空间从大于50M被耗尽到0M。

备注:一个相对谨慎的做法是将磁盘阈值设置为与操作系统所显示的内存大小一致。

(2)、磁盘限制

通过以下命令可以临时调整磁盘阈值

#设置具体大小,单位为KB/MB/GB
rabbitmqctl set_disk_free_limit <disk_limit>
#设置相对值,建议取值为1.0~2.0(相对于内存的倍数,如内存大小是8G,若为1.0,则表示磁盘剩余8G时,阻塞)
rabbitmqctl set_disk_free_limit mem_relative <fraction>

对应的配置文件配置如下:
disk_free_limit.relative=2.0
#disk_free_limit_absolute=50MB