【夯实RabbitMQ】如何保证消息不被重复消费?如何保证消息可靠传输?

目录

一、如何保证消息不被重复消费?

二、如何保证消息可靠传输


一、如何保证消息不被重复消费?

        消息大部分情况下是要对数据库造成影响的。重复消费的问题解决办法要看具体的业务。

        业务1:如果一条消息对应插入一条数据到数据库中,那么可以通过主键先查看数据库中是否已经插入了这条数据。

                     如果已经插入就不要重复插入了。可以通过为数据库中增加唯一索引的方式来控制重复插入。

                     或者更新一下数据库中的数据,这个要看具体的业务。

        业务2:如果消息有唯一键,可以考虑把消息的唯一键,比如订单号,存放到Redis中,并设置一个过期时间。

                     过期时间长短也要结合具体的业务场景。

二、如何保证消息可靠传输

        消息丢失可能会出现以下三种数据丢失问题: (1)生产者弄丢了数据(2)MQ弄丢了数据(3)消费者弄丢了数据

        (1)生产者弄丢了数据

        第一种解决方案是使用RabbitMQ的事务模式,不过这种方案是同步的,非常耗性能,一般不使用。

        第二种解决方案是使用confirm模式。生产者开启confirm模式后,每次的消息都会被分配一个id,然后写入到RabbitMQ中。RabbitMQ会响应一个ack代表消息已经成功写入MQ中。如果是nack,那么代表没有发送到MQ中失败,会触发回调接口。

        可以在这个回调接口里面重新发送消息。

   confirm模式异步的,在发完一个消息的后可以再发送另外的消息。RabbitMQ 接收了之后会异步回调你的一个接口通知你这个消息接收到了。

       

       (2)RabbitMQ 弄丢了数据

        如何防止MQ把消息弄丢了,那么就要支持持久化。包括持久化路由器队列消息,这样在重启的时候能够恢复这些数据。

        发送消息的时候将消息的 deliveryMode 设置为 2,就是将消息设置为持久化的。(默认就是2)

        创建队列持久化

        

        创建路由器持久化

        

       (3)消费者弄丢了数据(未确认消息)

         消费端刚接收到消息,然后系统就不可用了。如果是自动ack,那么MQ就认为消费端已经成功消费这条消息,但是实际上还没有来得及消费。所以必须关闭 RabbitMQ 的自动 ack。如果消费消息失败,那么会把消息重新退回MQ中,由MQ将此消息分配给其它消费者。

        

参考文档:RabbitMQ高可用

                  springboot整合rabbitMQ---生产者消息确认机制

                  MQ中间件-rabbitmq-生产者如何确保消息的不丢失(SpringBoot2.0版本)

阅读更多:从头开始学RabbimtMQ目录贴

你看我都这么努力的分享知识给你了,鼓励一下又何妨O(∩_∩)O

你的打赏是对我最好的支持!

                    

posted @ 2022-07-17 12:13  小大宇  阅读(328)  评论(0编辑  收藏  举报