MQ如何实现可靠性投递

一、消息可能出现丢失的情况

MQ如何实现可靠性投递
消息在生产者,MQ,消费者三个维度都有可能造成消息的丢失

  1. 生产者在向MQ服务器发送消息时,由于网络原因造成了消息发送失败,此时消息还未达到MQ造成了消息的丢失
  2. MQ接收到生产者发送过来的消息之后,保存在了内存当中,之后MQ服务器发生了重启,造成了消息丢失;或者MQ接收到消息之后正准备往硬盘存储,但是还未完成时,服务器发生故障,造成了消息丢失
  3. MQ将消息发送给消费者后,消费者在消息处理的时候出现了异常,虽然接收到了消息,但是因为出现了问题需要MQ重新发送;或者消费者在拿到消息之后还没来得及处理服务器就出现问题,发生了重启造成消息丢失

二、如何解决消息丢失情况

1. 生产者如何保证消息的可靠性投递

开启MQ的确认机制,当MQ接收到生产者发送过来的消息的时候,向生产者发送一个ACK信息,确认信息已经被MQ接收到了。

2. MQ如何保证消息的不丢失

开启消息队列的持久化机制,将接收到的消息都持久化到本地

3. 消费者如何保证消息的可靠性接收

开启消费者的手动确认功能,RabbitMQ在消费者接收消息处理的时候是自动确认的,只要消费者接收到消息之后,消费者就会向MQ返回消息确认收到信息,之后MQ就会删除持久化到本地的消息。但此时若消费者返回了确认信息之后,消费者在接收消息处理的时候出现了异常,或者服务器重启等故障,消费没有正常消费,那么MQ也不会重新发送消息了。因此我们需要开启手动确认机制,在确保消费者完全消费了消息之后再通知MQ消费发送成功

三、消费者端如何保证消费的幂等性

1. 产生幂等性问题原因

因为消费者端在接收MQ发送的消息的时候,可能会出现处理时间较长的情况,此时MQ在长时间没有收到消费者端返回的确认消息时,会尝试重新发一次消息,此时就可能会出现幂等性问题

2. 如何解决幂等性问题

将每个消息都设置一个唯一的UUID,在消费者消费了消息之后,把这个UUID存入到redis的set集合中,如果发现redis中已经存在了这个UUID,则表示这个消息被重复消费了,对这个消息做丢弃处理

上一篇:【架构师面试-消息队列-8】-消息队列的一般存储方式


下一篇:RabbitMQ 入门