这是我参与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 。它可能只是保存到缓存,而不是真正写到磁盘上。持久性保证并不强,但它对于我们简单的任务队列来说已经足够了。