总结RabbitMq消息丢失和消息重复消费问题

一.消息丢失

1.生产者发送到Mq消息丢失

原因:网络不稳定导致生产者向Mq发送消息时Mq没有接收成功,但是生产者认为Mq已经成功收到了消息,所以不会再次重新发送消息最终导致消息丢失。

解决方案:

        (1).事务机制。

           事务机制是同步的所以会很占用资源耗费服务器性能,导致降低Mq的吞吐量,所以不推荐使用。

        (2).confirm机制(发布确认机制)。

            confirm机制是异步的,生产者发送消息以后不需要等待回调通知Mq就可以继续发送下一个消息,Mq接收到消息后会异步通知给生产者消息接收成功与否。

  1.1 事务机制

生产者发送数据之前开启 Mq事务channel.txSelect,如果消息没有成功被Mq接收到,那么生产者会收到异常报错,此时就可以回滚事务 channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit如下:   

 1.2 confirm机制

在生产者那里设置开启confirm模式之后,如果消息成功写入 Mq中,Mq会给生产者回传一个ack消息,告诉你说这个消息发送成功与否。

2.Mq接收到消息之后丢失了消息

原因:Mq接收到生产者发送过来的消息,是存在内存中的,如果没有被消费完,此时Mq宕机了,那么再次启动的时候,原来内存中的那些消息都丢失了。

解决方案:开启Mq的持久化。当生产者把消息成功写入Mq之后,Mq就把消息持久化到磁盘。结合上面的说到的confirm机制,如果开启了消息的持久化,只有当消息成功持久化磁盘之后,才会回调生产者的接口返回ack消息,否则都算失败 。存入磁盘的消息不会丢失,就算Mq挂掉了,重启之后,他会读取磁盘中的消息,不会导致消息的丢失。

持久化配置:

1.队列持久化

 2.消息持久化

 

 持久化要起作用必须同时设置这两个持久化才行,Mq哪怕是挂了,再次重启,也会从磁盘上重启   恢复queue,恢复这个queue里的数据。

 要保证消息不丢失,我们开启队列、消息持久化的同时,也必须要开启 confirm(发布确认)模式。因 为即使我们在生产者中设置了队列持久化、消息持久化,但依然存在消息被传送到队列上,还没来得及存储在磁盘上,队列就宕机了,这种情况下消息也是会丢失的。所以在之前两步的基础上还是进行第三步:发布确认。三步操作加一起才能保证消息 从生产者到Mq服务器这个过程是不丢失的。
 

3.消费者导致消息丢失

原因:如果Mq成功的把消息发送给了消费者,那么Mq的ack机制会自动的返回成功,表明发送消息成功,下次就不会发送这个消息。但如果就在此时,消费者还没处理完该消息,然后宕机了,那么这个消息就丢失了。

解决方案:关闭Mq的自动ack,采用手动ack 。如果你还没处理完,就不会ack,没有调用手动的ack方法,消息会自动重新入队,这个时候mq会把这个消费分配给别的 consumer 去处理,消息是不会丢的。

消息应答机制 :为了保证消息在消费过程中不丢失,rabbitmq 引入消息应答机制,消息应答就是:消费者在接收到消息并且处理该消息之后,告诉 rabbitmq 它已经处理了,rabbitmq 可以把该消息删除了。

手动ack代码:

 

 二.重复消费

原因:正常情况下,消费者在消费消息的时候,消费完毕后,(手动应答)会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除;但是因为网络传输等故障,确认信息没有传送到消息队列,消息队列不知道消费者已经消费过该消息了,最终导致消息分发给其他的消费者,出现了重复消费。

解决方案:保证消息的幂等性。
以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
您好!对于 RabbitMQ 消息丢失消息积压和消息重复问题,一般可以从以下几个方面进行排查和解决: 1. 消息丢失: - 确保生产者成功发送消息RabbitMQ,可以通过确认机制(publisher confirms)来确保消息的可靠性发送。 - 确保消费者正确地从 RabbitMQ 接收消息并进行处理,可以使用消费者确认机制(consumer acknowledgements)来确保消息的可靠消费。 2. 消息积压: - 检查消费者的处理速度是否跟得上消息的生产速度,如果消费者处理速度较慢,会导致消息积压。可以增加消费者数量或优化消费者的处理逻辑来提高消费速度。 - 调整 RabbitMQ 的队列参数,包括队列的最大长度、最大优先级等,以适应不同的场景需求。 3. 消息重复: - 在生产者端,可以使用唯一标识符来标记每条消息,避免重复发送相同的消息。 - 在消费者端,可以使用幂等性操作来处理消息,即使消息重复消费也不会产生错误结果。例如,使用数据库的唯一键或者记录操作日志来避免重复处理。 此外,还可以考虑以下几点来提高 RabbitMQ 的可靠性和性能: - 使用持久化消息,确保消息RabbitMQ 服务器重启后不会丢失。 - 配置合适的消息 TTL(Time-To-Live)时间,防止长时间积压过期消息。 - 使用合适的集群和镜像队列设置,提高 RabbitMQ 的可用性和容错性。 希望以上信息能对您有所帮助!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dyddhr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值