RabbitMQ简易入门(4)-消息持久性

99 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

前言:  首先你需要安装RabbitMQ在您的本地,端口设置为5672. 如果使用不同的主机端口则配置需要调整。前文讲到了消息确认和消息重发。本篇文章我们来讲消息的耐用性。

消息持久性

之前讲到了,如何在消费者死亡时,确保任务还在。但是,如果RabbitMQ宕机的话,任务还是无法保留下来。

在RabbitMQ宕机时,内存中的消息的队列和消息会丢失,除非我们对这些数据额外做处理。需要做两件事来确保消息不会丢失:把队列和消息持久化到本地。这样就算服务器宕机,数据也能保留下来。

首先,我们需要确保队列将在RabbitMQ节点重新启动后存活下来。我们先要把队列的持久化状态开启。

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

虽然此命令本身是正确的,但它不会在我们的设置中工作。这是因为我们已经定义了一个名为"你好"的队列,该队列不耐用。RabbitMQ 不允许您重新定义具有不同参数的现有队列,并将错误返回到任何尝试这样做的程序。但有一个快速的解决方法 - 让我们宣布一个不同名称的队列,例如test_queue:

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

这一queue_declare变化需要同时应用于生产者和消费者代码。

在这一点上,我们相信,即使RabbitMQ重新启动,test_queue队列也不会丢失。现在,我们需要通过修改、delivery_mode=2来将我们的信息标记为持久性。

channel.basic_publish(exchange='',
                      routing_key="test_queue",
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # make message persistent
                      ))

将消息标记为持久性并不能完全保证消息不会丢失。虽然它告诉RabbitMQ将消息保存到磁盘中,但是RabbitMQ接受消息并且尚未保存时,仍有很短的时间窗口。此外,RabbitMQ 不会为每条消息都做fsync 。它可能只是保存到缓存,而不是真正写到磁盘上。持久性保证并不强,但它对于我们简单的任务队列来说已经足够了。