RabbitMQ 消息持久化

持久化

持久化涉及到队列持久化和消息持久化,根据实际情况需要,看自己的具体需求。

消息确认机制使得客户端在崩溃的时候,服务端消息不丢失,但是如果rabbitmq奔溃了呢?该如何保证队列中的消息不丢失?

  • 队列持久化
    生产者代码,声明queue的时候,设置durable=True 参数
    具体代码如下:
import time

import pika

#  https://www.cnblogs.com/koka24/p/5304454.html
credentials = pika.PlainCredentials('xiaoxia', 'xiaoxia')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '47.244.*.*', 5672, '/', credentials))
# 声明queue
channel = connection.channel()
# 声明queue
channel.queue_declare(queue='round_robin_queue_test7', durable=True)
# n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
n = 20
sum = 0
counter = 1
while counter <= n:
    channel.basic_publish(exchange='',  # Producer只能发送到exchange,它是不能直接发送到queue的,发送到默认exchange
                          routing_key='round_robin_queue_test7',  # 路由key发送指定队列
                          body='Hello World:' + str(counter))  # 发送的消息
    time.sleep(1)
    counter += 1
print(" [x] Sent 'Hello World!'")
connection.close()

看看web端管理后台情况
RabbitMQ 消息持久化_第1张图片
现在重启rabbitMQ,看看web后台Rabbit运行情况
RabbitMQ 消息持久化_第2张图片
可以看到队列还在,但是消息已经丢失了,其它未设置参数的队列全部消失了。

  • 消息持久化
      我们刚才实现了在rabbitmq崩溃的情况下,就队列本身保存下来,重启后队列还在。接下来我们要将消息也保存下来,即消息的持久化

发送端代码:

import time
import pika
credentials = pika.PlainCredentials('xiaoxia', 'xiaoxia')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '47.244.*.*', 5672, '/', credentials))
# 声明queue
channel = connection.channel()
# 声明queue
channel.queue_declare(queue='round_robin_queue_test7', durable=True)
# n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
n = 20
sum = 0
counter = 1
while counter <= n:
    channel.basic_publish(exchange='',  # Producer只能发送到exchange,它是不能直接发送到queue的,发送到默认exchange
                          routing_key='round_robin_queue_test7',  # 路由key发送指定队列
                          body='Hello World:' + str(counter),
                          properties=pika.BasicProperties(
                              delivery_mode=2,  # make message persistent
                          ))
    # 发送的消息
    time.sleep(1)
    counter += 1
print(" [x] Sent 'Hello World!'")
connection.close()

看看重启rabbitMQ 前后,web端后台情况是一模一样的,队列和消息都没有丢失。这样就做到了队列和消息的持久化。
RabbitMQ 消息持久化_第3张图片

这个时候运行Receiver接收端,也是能够正常收到消息的。接收端也要声明durable=True 属性

channel.queue_declare(queue='round_robin_queue_test7',durable=True)


import pika
credentials = pika.PlainCredentials('xiaoxia', 'xiaoxia')
# 建立连接
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '47.244.*.*', 5672, '/', credentials))
channel = connection.channel()
channel.queue_declare(queue='round_robin_queue_test7',durable=True)
def callback(ch, method, properties, body):  # 定义回调函数用于取出队列中的数据
    print(" [x] Received %r" % body)
    ch.basic_ack(delivery_tag=method.delivery_tag)  # 发送ack消息
channel.basic_consume(queue='round_robin_queue_test7',
                      on_message_callback=callback,
                      auto_ack=False)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()  # 监听数据

总结

  1. 队列持久化需要在声明队列时添加参数 durable=True,这样在rabbitmq崩溃时也能保存队列
  2. 仅仅使用durable=True ,只能持久化队列,不能持久化消息
  3. 消息持久化需要在消息生成时,添加参数properties=pika.BasicProperties(delivery_mode=2)

你可能感兴趣的:(RabbitMQ)