消息的持久化是消息队列必备的功能之一。在这篇文章中,就介绍一下RabbitMQ的持久化机制,和它的使用。

 

队列的持久化

在前几篇的例子中,我们常常看到如下定义queue的方法:

channel.QueueDeclare("Q1", false, false, false, null);

方法的第四的参数autoDelete,一般都会输入false。文档描述这个参数如果是true的话,意思是:如果这个queue不再使用(没有被订阅)的话,server就会删除它。在我的测试过程中,只要是连接改queue的所有接收者都断开连接的话,该queue就会被删除,即使里面还有没有处理的消息。RabbitMQ的重启也同样会删除他们。如果输入的是false,那与之相连的客户端都断开连接的话,服务是不会删除这个队列的,队列中的消息也就会存在。发送端在没有客户端连接的时候也可以把消息放入改队列,客户端起来的时候,就会得到这些消息。但是如果RabbitMQ服务重启的话,该队列就没有了,里面的消息自然也就没有了。

第三个参数是exclusive,文档描述说,如果是true,那么申明这个queue的connection断了,那么这个队列就被删除了,包括里面的消息。

第二个参数durable,文档描述说,如果是true,则代表是一个持久的队列,那么在服务重启后,也会存在。因为服务会把持久化的queue存放在硬盘上,放服务重启的时候,会重新申明这个queue。当然必须是在autoDelete和exclusive都为false的时候。队列是可以被持久化,但是里面的消息是否为持久化那还要看消息的持久化设置。也就是说,如果重启之前那个queue里面还有没有发出去的消息的话,重启之后那队列里面是不是还存在原来的消息,这个就要取决于发送者在发送消息时对消息的设置了。

 

消息的持久化

接上文,如果要在重启后保持消息的持久化必须设置这个消息是持久化的。设置是在发送者发送的时候,比较简单,代码如下:

 

IBasicProperties properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2;
channel.BasicPublish("", "TaskQueue", properties, bytes);

 

DeliveryMode等于2就说明这个消息是persistent的。1是默认是,不是持久的。

 

在接收者接收消息并处理的时候会出现各种各样的问题:抛出异常导致与RabbitMQ连接断开,程序挂掉,网络问题等等。往往在出现这些问题的时候我们通常都希望队列能保存这些消息,并在程序再次起来的时候能够重新处理,或如果是负载均衡的模式下,能够把这个消息重新分配给其他的同等的接受者来处理。这同样也是RabbitMQ对消息持久化的一种功能。这我们在消息的传输控制中做详细的说明。

posted on 2012-09-28 15:49  nick hao  阅读(4275)  评论(0编辑  收藏  举报