RabbitMQ如何保证消息的可靠性,保证消息不丢失?

RabbitMQ消息的可靠性就是指在消息传递过程中,保证消息被正确传递和处理,确保消息不会丢失、重复或错误地传递。

想要保证消息队列的可靠性,需要知道消息丢失的几种情况

  1. 生产者发送消息未到达交换机

  2. 消息到达交换机,没有正确路由到消息队列

  3. 消费者收到消息,还没消费完,消费者出现异常错误

  4. 最极端的情况是MQ宕机,消息队列中的消息没了

如何保证消息不丢失?

需要根据具体的业务场景和需求来选择合适的方法,来保证消息可靠性。

首先需要看消息的重要性?如果是不太重要的消息,例如验证码等信息,丢失了也不会造成太大的影响;如果是重要的消息,就需要相应的处理。

第一种:开始事务。

在RabbitMQ中,可以使用RabbitMQ中提供的事务功能,在传输消息之前,添加事务,如果消息传输的过程中出错了,就会回滚事务,如果没有出现错误,就提交事务。但是,RabbitMQ中的事务机制是同步的,使用事务的话,比较消耗性能,所以一般不用事务功能。

第二种:生产者确认机制。

confirm模式。简单来说就是 把消息正确的放在 exchange交换机,成功了就返回ack确认帧,失败了就返回nack。这个confirm回调函数需要在发送消息前时指定,因为每个业务处理confirm都不一样。

return模式。简单来说就是 在成功到达了交换机后,消息没有正确到达队列,才会触发回调函数。

第三种:消费者确认机制。有三种模式

none模式。只用消息到达消费者那里,就直接返回ack到MQ,MQ接收到ack,就会把队列中相应的消息删除。其缺点就是如果消费者出现异常,就会造成消息丢失,所以这个none模式一般不用。

manual模式。就是自己手动发送ack帧,消费成功时,调用API给MQ返回ack帧;消费失败,调用API给MQ返回nack,并根据业务需求处理消息去向。

auto模式(默认值)。当消息没有出现异常时,返回ack给MQ;如果出现异常,则返回nack,并根据失败策略处理消息。

这个失败策略有三种:

  • RejectAndDontRequeueRecoverer:重试耗尽后,消息不会重新放入队列,而是直接丢弃消息。这个是默认的失败策略

  • ImmediateRequeueMessageRecoverer:重试耗尽后,重新将消息放入队列

  • RepublishMessageRecoverer:重试耗尽后,将失败的消息发布到指定的交换机

第四种:持久化机制

持久化就是防止在系统或者服务器在异常情况下丢失消息

交换机持久化:默认持久化,也可以通过,在创建时,将指定的交换机、队列标识为持久化

队列持久化:默认持久化

消息持久化:默认持久化,也可以在发送消息时,使用Message对象,设置其delivery-mode为persistent,也就是持久化消息

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ 通过持久化和确认机制来保证消息可靠性。 在发送消息时,可以设置消息的 delivery mode 为 2,表示消息需要被持久化。持久化的消息会被写入磁盘,即使 RabbitMQ 服务器宕机或重启,消息也不会丢失。 在接收消息时,可以使用确认机制。当消费者成功处理了一条消息后,会向 RabbitMQ 发送确认消息。如果 RabbitMQ 收到确认消息,就会将该消息从队列中删除,否则该消息会被重新发送。通过确认机制,可以保证消息不会被重复消费。 以下是一个简单的 RabbitMQ 发送和接收消息的示例代码: ``` import pika connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() # 声明队列 channel.queue_declare(queue='hello', durable=True) # 发送消息 channel.basic_publish(exchange='', routing_key='hello', body='Hello World!', properties=pika.BasicProperties(delivery_mode=2)) print(" [x] Sent 'Hello World!'") # 接收消息 def callback(ch, method, properties, body): print(" [x] Received %r" % body) ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1) channel.basic_consume(queue='hello', on_message_callback=callback) print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming() ``` 在这个示例中,我们设置了队列的 durable 属性为 True,表示队列需要被持久化。在发送消息时,我们设置了消息的 delivery mode 为 2,表示消息需要被持久化。在接收消息时,我们使用了确认机制,通过调用 ch.basic_ack() 方法确认消息已经被消费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值