队列和消息都可以持久化。
持久化的目的就是让消息不丢失。
RabbitMQ本身退出,或者由于某种原因崩溃时造成的消息丢失。
RabbitMQ一旦宕机,就会造成队列和消息都丢失了。
RabbitMQ重启之后,非持久化的队列和消息都不存在了。
队列持久化
注意:如果要把原来的非持久化队列改成持久化队列,是会报错的。
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for queue 'ack_queue' in vhost '/': received 'true' but current is 'false', class-id=50, method-id=10)
正确的持久化队列姿势:先删除原来非持久化的队列,重新的创建持久化的队列。
创建持久化的队列
//声明队列
//第二个参数 durable为true表示持久化队列和消息
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
消息持久化
消息的发送者在发送消息的时候,对消息进行持久化。
MessageProperties.PERSISTENT_TEXT_PLAIN
//发送消息
//第三个参数 MessageProperties.PERSISTENT_TEXT_PLAIN
channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));
注意:消息持久化不能完全保证不丢失消息,尽管它告诉rabbitmq将消息保存到磁盘,但是依然存在当消息刚准备存储到磁盘的时候,但是还没有存储完,消息还在缓存的一个间隔点。此时消息并没有真正的写入磁盘。持久性保证并不强。但是对于简单任务队列而言,这已经绰绰有余了。
如果需要强有力的持久化策略需要发布确认模式,后续会介绍。