声明队列使用的queueDeclare()方法包含一系列入参,这些入参定义了队列的属性。需要注意的是,一旦队列创建后,其属性就不能改变了。若声明队列使用的入参与队列的属性不符,将会报错。
运行第2章的发送方代码,再将queueDeclare()中的入参中durable参数修改为true后运行,将会有如下报错:
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 'Queue_Java' in vhost '/':
received 'true' but current is 'false', class-id=50, method-id=10)
...
关键的报错信息为“inequivalent arg ‘durable’ for queue ‘Queue_Java’ in vhost ‘/’: received ‘true’ but current is ‘false’”,可见队列当前持久化(durable)的属性为false,可收到了true,导致报错。
以下逐一说明声明队列时各入参含义。
3.1 持久化
RabbitMQ的队列和消息存放于内存中,在出现任何异常情况,导致RabbitMQ异常中止,内存中的数据将会丢失。若要在RabbitMQ从异常恢复后仍然保存有异常中止前的消息,就需将消息持久化,即将消息同时保存于磁盘中。RabbitMQ可将消息保存到Erlang自带的Mnesia数据库中,当RabbitMQ重启之后会读取该数据库。
声明队列的方法中,“durable”参数即指定队列是否是持久化的。使消息持久化,需要队列和消息都是持久化的,并且通常交换机也应该是持久化的。RabbitMQ的默认交换机“(AMQP default)”是持久化的,对于与其绑定的队列,将队列声明为持久化的队列,并发送持久化的消息,即可将消息持久化。
// 声明持久化队列,durable = true
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
// 发送持久化消息
byte[] message = "This is Java's message".getBytes();
AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties().builder()