rabbitmq消息持久化

RabbitMQ支持消息的持久化,也就是数据写在磁盘上,为了数据安全考虑,我想大多数用户都会选择持久化。消息队列持久化包括3个部分:
1、exchange持久化,在声明时指定durable => 1
2、queue持久化,在声明时指定durable => 1
3、消息持久化,在投递时指定delivery_mode => 2(1是非持久化)或者设置MessageProperties.PERSISTENT_TEXT_PLAIN
如果exchange和queue都是持久化的,那么它们之间的binding也是持久化的。如果exchange和queue两者之间有一个持久化,一个非持久化,就不允许建立绑定。

Java实现

factory.setUsername("guest");
factory.setPassword("guest");
factory.setHost("127.0.0.1");
factory.setVirtualHost("/");
factory.setPort(5672);
       
/**
 * 创建连接
*/
Connection connection = factory.newConnection();
        
/**
 * 创建信道
*/
Channel channel = connection.createChannel();
        
/**
  * 声明一个type=topic持久化的 非自动删除的交换器
  * 第三个参数表示是否持久化
*/
        
channel.exchangeDeclare(EXCHANGE_NAME, "direct", true, false, null);

/**
 * 声明一个持久化 非排他的 非自动删除的队列,第二个参数表示是否持久化
*/
channel.queueDeclare(QUEUR_NAME, true, false, false, null);

  
/**
 * 将交换器与队列通过路由键绑定
*/        
bindingKey = "#." + bindingKey + ".#";
channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
       
/**
 * 发送一条持 久化消息
 * MessageProperties.PERSISTENT_TEXT_PLAIN表示
*/
String message="Hello RabbitMq!";
channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN , message.getBytes());
        
/**
 * 关闭资源
*/
channel.close();
connection.close();

其中关于方法的定义
1、queueDeclare

Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,Map<String, Object> arguments) throws IOException;

参数释义如下

  1. queue:队列名称
  2. durable: 是不持久化, true ,表示持久化,会存盘,服务器重启仍然存在,false,非持久化
  3. exclusive : 是否排他的,true,排他。如果一个队列声明为排他队列,该队列公对首次声明它的连接可见,并在连接断开时自动删除
  4. autoDelete::是否自动删除,true,自动删除,自动删除的前提:至少有一个消息者连接到这个队列,之后所有与这个队列连接的消息都断开时,才会自动删除,备注:生产者客户端创建这个队列,或者没有消息者客户端连接这个队列时,不会自动删除这个队列

2、exchangeDeclare

Exchange.DeclareOk exchangeDeclare(String exchange,
                                              String type,
                                              boolean durable,
                                              boolean autoDelete,
                                              boolean internal,
                                              Map<String, Object> arguments) throws IOExcept

参数释义

  1. exchange :交换器的名称
  2. type : 交换器的类型,常见的有direct,fanout,topic等
  3. durable :设置是否持久化。durable设置为true时表示持久化,反之非持久化.持久化可以将交换器存入磁盘,在服务器重启的时候不会丢失相关信息。
  4. autoDelete:设置是否自动删除。autoDelete设置为true时,则表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后,所有与这个交换器绑定的队列或者交换器都与此解绑。不能错误的理解—当与此交换器连接的客户端都断开连接时,RabbitMq会自动删除本交换器
  5. internal:设置是否内置的。如果设置为true,则表示是内置的交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式。

Python声明实现

logger.info('Declaring exchange %s', exchange_name)
# 声明exchange,durable表示是否持久化
self._channel.exchange_declare(callback = self.on_exchange_declareok,
              exchange = exchange_name,
              exchange_type = ’topic‘,
              durable = True,
              auto_delete = False,
              passive = False)
# 声明队列,durable表示是否持久化
logger.info('Declaring queue %s', queue_name)        
self._channel.queue_declare(callback = self.on_queue_declareok, 
              queue = queue_name, 
              durable = True, 
              auto_delete = False, 
              passive = False)
# 绑定key、exchange、queue
logger.info('Binding %s to %s with %s',exchange_name, queue_name, ROUTING_KEY)
self._channel.queue_bind(self.on_bindok,queue_name,exchange_name, ROUTING_KEY)

# 发送消息
logger.info('Published message # %s', message)
self._channel.basic_publish(exchange_name, routing_key, message,properties=pika.BasicProperties(delivery_mode=2, ) )

持久化的后遗症

比如说你初始化了一个队列msgs.你会发现它真的持久了!每次服务器端重启后,通过list_queues命令查看的时候都存在.但是时间久了,这个msgs我们并不需要了,想清除这个队列只能删除它所在的vhost,然后再重建vhost,再设置vhost的权限.
rabbitmqctl delete_vhost /
rabbitmqctl add_vhost /
rabbitmqctl set_permissions -p / rainbird ‘.’ '.’ ‘.*’

要注意,如果这个操作过程中有接收端处于连接状态它们不会自动断开,但也不会再收到消息,需要手动重新连接一下.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值