当前位置:   article > 正文

RabbitMQ如何保证消息的可靠传输?_rabbitmq如何保证消息的可靠性传输

rabbitmq如何保证消息的可靠性传输

 

一、消息的可靠传输

消息的可靠传输是指消息从Producer发送到Broker,再到Consumer被消费的整个过程中,要确保消息不丢失,如果出现消息丢失的情况,系统也要能发现,并执行一些补偿措施,而不是消息丢了都不知道,石沉大海。

如图,消息从Producer发送到Broker再到Consumer被消费的整个传输过程中,因为网络中断等原因,可能会造成消息的丢失,出现消息丢失的情况有以下几种:

1、Producer将消息发送到交换机的路上,因为网路中断等原因,消息丢失;

2、消息到达了交换机,但是交换机根据路由规则如果找不到匹配的queue,消息也会被抛弃;

3、消息发送到Broker后会存放在内存中(没有开启持久化的情况下),如果Consumer还没来得及消费,Broker挂掉了,那么消息也会丢失;

4、默认情况下,RabbitMQ开启的是自动确认autoack,即Consumer收到消息还没有处理时,就会返回一个确认应答ack,Broker收到ack,则认为消息已消费成功,会将该消息从队列中删除。如果Consumer在返回ack后宕机或者在处理消息时发生异常,就会造成消息丢失;

二、怎么保障可靠传输?

要保证消息可靠传输,就要解决上面的几个问题,下面我们来看一下怎么解决这些问题。

1、生产者将消息发送到交换机的路上,消息丢失怎么办?

一般有两种解决方案:

① 开启事务,Producer发送消息时开启事务,如果发生异常事务回滚,但开启事务就意味着降低性能,尤其在高并发环境,慎用,本文demo不用这种方法!

② 开启生产者confirm机制,在SpringBoot中,在application.yml配置文件中设置spring.rabbitmq.publisher-confirm-type=correlated,生产类实现RabbitTemplate.ConfirmCallback接口,重写confirm方法,不管消息是否成功发送到交换机,都会回调confirm方法,可以在这个方法里做判断处理。

2、消息到达了交换机,但是没有找到匹配的队列造成的消息丢失怎么应对?

SpringBoot中,在application.yml配置文件中设置spring.rabbitmq.publisher-returns=true,生产者类实现RabbitTemplate.ReturnCallback接口,重写returnedMessage方法,在交换机没有找到匹配队列时会回调returnedMessage方法,可在这个方法内做重试补偿。如果找到了匹配队列,就不再回调这个方法。

3、消息到达Broker后会暂存在内存中,如果Consumer还没来得及消费,Broker挂掉了,导致的消息丢失问题怎么解决?

设置持久化,以保证即使Broker挂掉,服务重启后消息依然会恢复,

① 将Exchange设置为持久化的;

② 将Queue设置为持久化的;

③ 将message设置为持久化的。

但这里还有个问题,设置了持久化的消息存入Broker之后,还需要一段时间才能存入磁盘(虽然很短,但不能忽视),因为Broker并不会为每条消息都实时同步存盘,如果这个很短的时间内发生宕机、异常、重启等情况,消息也会丢失,解决办法是引入"RabbitMQ的镜像队列"(RabbitMQ集群,Master挂了Slave会换上去充当Master)。

4、Consumer宕机或处理消息时发生异常导致的消息丢失怎么应对?

关闭autoack,开启手动ack(将autoAck参数为false)。消费者在处理完成后再发送ack给Broker,Brok

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/391296
推荐阅读
相关标签
  

闽ICP备14008679号