03.保证可靠消费常识原理
生产者确认机制:确保消息成功到达交换器和队列。通过ACK机制,生产者可获知消息是否投递成功。
持久化机制:队列、交换器和消息均可设置持久化,防止RabbitMQ宕机后丢失消息。
消息确认机制:消费者需手动ACK消息,确保成功消费。未确认的消息会重新入队,防止消费失败。
死信队列与重回队列:处理未成功消费或超时的消息,确保消息不会丢失。
# 01.如何保证消息的可靠性
# 0、rabbitmq的四个阶段
- 第一,生产者发出后
保证到达了MQ
- 第二,MQ收到消息保证分发到了消息
对应的Exchange
- 第三,Exchange分发消息入队之后
保证消息的持久性
- 第四,消费者收到消息之后
保证消息的正确消费
# 1、生产者确认机制
生产者确认机制
,生产者发送消息时,RabbitMQ提供ACK机制,确保消息成功到达交换器和队列
# 1)生产者发出后保证到达了MQ
1)一种是
消息发送确认
- 这种是用来确认生产者将消息发送给交换器,交换器传递给队列的过程中,消息是否成功投递
- 送确认分为两步,一是确认是否到达交换器,二是确认是否到达队列
2)举例说明
比如一条订单消息,当消息确认到达MQ确认之后再行入库或者修改订单的节点状态
如果消息没有成功到达MQ可以进行一次记录或者将订单状态修改
Tip:消息确认失败不只有消息没发过去会触发,消息发过去但是找不到对应的Exchange,也会触发
# 2)MQ发送到exchange
生产者的发送消息处理好了之后,我们就可以来看看MQ端的处理
MQ可能出现两个问题:
- 消息找不到对应的Exchange
- 找到了Exchange但是找不到对应的Queue
这两种情况都可以用RabbitMQ提供的mandatory参数来解决,它会设置消息投递失败的策略
有两种策略:自动删除或返回到客户端
我们既然要做可靠性,当然是设置为返回到客户端
# 2、持久化
队列、交换器和消息
可以设置为持久化
,以防RabbitMQ宕机后丢失数据
Exchange分发消息入队之后保证消息的持久性
消息入队之后MQ宕机,怎么保证消息不丢
消息的持久化要做,但是不能只做消息的持久化,还要做队列的持久化和Exchange的持久化
创建Exchange和队列时只要设置好持久化,发送的消息默认就是持久化消息
设置持久化时一定要将Exchange和队列都设置上持久化:
- 单单只设置Exchange持久化,重启之后队列会丢失
- 单单只设置队列的持久化,重启之后Exchange会消失
- 既而消息也丢失,所以如果不两个一块设置持久化将毫无意义
# 3、消息确认机制
- 消费者在成功消费消息后手动发送ACK给RabbitMQ,只有在接收到ACK后消息才会从队列中删除
消费者无法正常消费,那这个消息怎么处理的
其实就是消费者的消息确认
打开手动消息确认之后,只要我们这条消息没有成功消费,无论中间是出现消费者宕机还是代码异常
只要连接断开之后这条信息还没有被消费那么这条消息就会被重新放入队列再次被消费
当然这也可能会出现重复消费的情况,不过在分布式系统中幂等性是一定要做的,所以一般重复消费都会被接口的幂等给拦掉
所谓幂等性就是:一个操作多次执行产生的结果与一次执行产生的结果一致
幂等性相关内容不在本章讨论范围~所以我就不多做阐述了
# 4、死信队列
死信队列
(DLX, Dead Letter Exchange),未成功消费或超时的消息可以通过死信队列重新处理,避免消息丢失
# 5、重回队列
- 消费者在处理失败时可以将消息重新放回队列供其他消费者消费