浅谈 RabbitMQ(二)解决消息丢失
浅谈 RabbitMQ(一)工作模型与 Exchange 类型
目录
一、消息传递分析
RabbitMQ的具体结构图参考笔者上一篇文章,下面画个消息传递的简图
从上图可知,要确保一个消息正确的传递,需要在四个传递阶段都能正确传递:
- 确保消息成功由生产者发送到RabbitMQ服务器
- 确保消息被交换机路由到正确的队列
- 确保消息在队列中不丢失
- 确保消息成功被消费者消费
二、消息丢失的几种情况
知道了消息如何传递,自然也就知道了消息丢失的情况了:
- 在生产者发送到RabbitMQ服务器时丢失
- 在交换机路由到队列时丢失
- 在队列中丢失
- 在消费时丢失
三、消息丢失解决方案
那么解决消息丢失自然也是根据这几种情况来分析了:
(1)解决生产者发送消息到MQ的丢失
1. 服务端确认-事务模式
生产者每发送一次消息,MQ就响应一次。这种模式效率低,不推荐
2. 服务端确认-确认模式
生产者发送消息后,服务器发送确认ACK给生产者,根据确认的方式又分为三种:
- 单条确认:生产者每发送一次消息,服务器发送确认一次,类似于事务模式,效率低
- 批量确认:设置发送消息次数后,服务器发送确认
- 异步确认:生产者监听服务器发送的确认事件,由服务器决定何时确认
(2)解决在交换机路由时的消息丢失
-
在无法路由到队列时将消息回发给生产者
-
创建交换机时指定一个备份交换机,路由失败时将消息发送到备份交换机
(3)解决在队列时的消息丢失
- 创建队列时设置队列持久化
- 消息持久化
(4)解决在消费时的消息丢失
消费者消费消息时默认为自动确认,即消费者刚收到消息时就给MQ发送ACK确认,此时MQ会将消息出队;如果想要在消费的逻辑处理完成后再确认消息,就需要消费者设置手动确认ACK,假如在消费过程中发生异常,无法发送确认给MQ服务器,消息将无法出队,导致堆积,所以需要在finally块中设置unAck或者将消息回发给MQ服务器
(5)其它保证消息正确消费的情况
- 补偿机制
比如生产者在发送消息到MQ时,始终收不到确认,那么就需要重发消息,但是重发也不能一直发送,会导致重复消息堆积。所以有两种解决方案:① 设置等待确认超时,超时后再重发消息;② 重发时控制次数
- 消息幂等
假如在消费过程中同一消息被消费多次,在特定场景中将产生重大影响,比如转账等,所以需要保证同一条消息在消费多次后保证操作一致(类似于接口幂等性:重复调用时保证数据一致)
作者:超级鲨鱼辣椒
转载请注明原文链接:https://www.cnblogs.com/jinzlblog/p/15147420.html