RabbitMQ的可靠性投递,也就是在使用RabbitMQ实现异步通信的时候,消息丢了怎么办,消息重复消费怎么办?在RabbitMQ里面提供了很多保证消息可靠投递的机制,这个也是RabbitMQ的一个特性。
在说可靠性投递的时候,必须要明确一个问题,因为效率与可靠性是无法兼得的,如果要保证每一个环节都成功,势必会对消息的收发效率造成影响。所以如果是一些业务实时一致性要求不是特别高的场合,可以牺牲一些可靠性来换取效率。比如发送通知或者记录日志的这种场景,如果用户没有收到通知,不会造成业务影响,只要再次发送就可以了。
下图是RabbitMQ的工作模型,其中标出的是需要保证消息可靠性的地方
-
消息从生产者发送到Broker
生产者把消息发到Broker之后,怎么知道自己的消息有没有被Broker成功接收?
-
消息从Exchange路由到Queue
Exchange是一个绑定列表,如果消息没有办法路由到正确的队列,会发生什么事情?应该怎么处理?
-
消息在Queue中存储
队列是一个独立运行的服务,有自己的数据库(Mnesia),它是真正用来存储消息的。如果还没有消费者来消费,那么消息要一直存储在队列里面。如果队列出了问题,消息肯定会丢失。怎么保证消息在队列稳定地存储呢?
-
消费者订阅Queue并消费消息
队列的特性是什么?FIFO。队列里面的消息是一条一条的投递的,也就是说,只有上一条消息被消费者接收以后,才能把这一条消息从数据库删掉,继续投递下一条消息。那么问题来了,Broker怎么知道消费者已经接收了消息呢?
下面,我们就从这四个方面来看,RabbitMQ是如何保证消息可靠性的。