RabbitMQ消息持久化


一、前言

之前我们讲,RabbitMQ server是采用轮询的方式,公平的依次给每一个消费者。下面我们就来讲讲RabbitMQ 是如何把消息持久化的。

1.1、RabbitMQ手动确认

是消费者处理消息完毕之后,需要RabbitMQ server手动去确认是否处理完毕,而不是自动确认。

通过 rabbitmqctl list_queues查看队列的消息。

如果想要清楚消息,则需要手动确认。确认代码如下:

ch.basic_ack(delivery_tag=method.delivery_tag)
#!/usr/bin/env python
#-*- coding:utf-8 -*-
__author = "susu"
## 消费者有可能在其他的机器上
import pika,time
credentials = pika.PlainCredentials('junesu', '123456')
#连接信息
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.5.132',5672,'/',credentials))
channel = connection.channel()
channel.queue_declare(queue="xiaosusu")
def callback(ch, method, properites, body):
    print("--->", ch, method, properites)
    # time.sleep(30)
    print(" [x] Received %r" % body)
    ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_consume( 
    callback,  
    queue="xiaosusu", 
    # no_ack=True
    )
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
consumers

 再来看看效果

1.2、消息处理完毕,为什么需要手动确认一下呢?

  因为你调用的这个callback函数之后,它可能处理完收到这个消息,它接下来要干很多事情,就是说跟这个消息没有关系了。就是函数没有处理完,但是消息已经处理完了,所以你要等到函数处理完可能要花2个消息,那服务器要等2个小时候之后才能收到,所以这个也是手动确认也会处理。

 二、RabbitMQ消息持久化

 队列里面还为消息等着客户端(消费者)去接收,但是这个时候服务器端down机了,这个时候消息是否还在?带着这个疑问,我们来做几个实验。

 2.1、重启队列和消息丢失

说明:服务端发送消息->重启RabbitMQ

服务端传统的声明queue

channel.queue_declare(queue="xiaoxiaosu")

 这种情况下消息都在内存里面,如果down了就down了,队列和消息都没有了

2.2、队列持久化

说明:我们把队列进行持久化,就算重启我的RabbitMQ服务,我的队列也不会丢。

队列持久化,在服务端(生产者)声明queue的时候,需如下定义:

channel.queue_declare(queue='xiaosusu', durable=True)#durable=>持久化

2.3、队列和消息都持久化

说明:现在我想队列和消息都持久化,那怎么办呢。

队列和消息都持久化,在服务端(生产者)声明queue的时候,需如下定义:

channel.queue_declare(queue="xiaosusu",durable=True) #durable=>持久化
 
channel.basic_publish(exchange="",
                      routing_key="xiaosusu",  #queue的名字
                      body="hello world",
                      properties=pika.BasicProperties(delivery_mode=2,) # make message persistent=>使消息持久化
                      )  #body是你发送的内容

 总结:如果想队列和消息都保证持久化,就必须是声明和发消息的时候,都需要声明持久化。

注:如果你在服务端声明持久化,在客户端也必须声明queue的时候也需要声明持久化,不然的话就会报错,声明持久化的方式和服务端一样

 四、总结

 

  1.  RabbitMQ在服务端没有声明队列queue持久化(durable=True)时,队列是存在内存中的,服务端down机了,队列也随之消失。
  2. RabbitMQ在服务端只声明queue持久化,但是在发送消息时,没有声明持久化(properties=pika.BasicProperties(delivery_mode=2,)),服务器down机,只保留队列,但是不保留消息。
  3. RabbitMQ在服务端声明queue持久化,并且在发消息时也声明了持久化,服务down机重启后,队列和消息都能得到保存。
  4. 服务端声明持久化,客户端想接受消息的话,必须也要声明queue时,也要声明持久化,不然的话,客户端执行会报错。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM