01-RabbitMQ-消息不丢失
在微服务中,MQ的技术必不可少
场景:
在大部分场景中,我们都是保证AQ高可用性的,这就引出了一个问题——如何保证消息不丢失呢?
这是消息的发送和消费流程
左侧publisher:消息的发送者
exchange:交换机
queue:消息队列
consumer:消息的消费者
在这个流程中,在每个环节都有可能丢失消息
那么就有这么几个环节和它们的解决办法:
1、消息发送到MQ时产生丢失
解决:publisher confirm
如果消息正常发送到队列:publish-confirm ack
如果消息发送到交换机失败:publish-confirm nack
如果消息从交换机到队列失败:publish-return ack
处理方式:
2、MQ宕机
MQ默认是内存存储消息,开启持久化功能可以确保缓存在MQ中的消息不丢失
3、消费者导致消息丢失
RabbitMQ支持消费者确认机制
一般选择第二种,自动确认。
出现异常解决方法:
总结:
1、生产者确认
2、持久化
3、消费者确认auto,spring监听并发送ack
4、消费者失败重试,设置重试次数,发送到异常交换机,人工处理
02-RabbitMQ-消息的重复消费问题
比如说:
现在消费者消费了某个消息,但这个ack还没有发送到MQ中时,就发生了宕机。
这个时候ack未发送,消息仍然存储在MQ消息队列中,它会被重复消费。
解决方案:
加锁性能较低,优先采用唯一标识
这个适用于任何MQ
03-RabbitMQ-死信交换机(RabbitMQ延迟队列)
超时订单:比如订单需要在10min中进行消费
限时优惠:11.11等等,优惠还剩…时间
定时发布:选择时间发布说说等
延迟队列 = 死信交换机 + TTL(生存时间)
死信交换机:
对于死信的处理:
一定要设置属性,指定死信交换机
如果一个队列中的消息TTL结束但仍未消费,则变成死信。
ttl超时分两种情况:
ttl时间取两者更短的使用
也可以直接安装延迟队列插件
04-RabbitMQ-消息堆积怎么解决
生产者发送消息的速度 >>消费者消费消息的速度
导致队列中的消息堆积,使消息成为死信,可能产生消息丢弃
解决方案:
1、增加消费者
2、开启线程池(基于cpu)
3、开启惰性队列
对于扩大队列,可以使用惰性队列lazyqueue:
它把消息存储在磁盘中,只有需要消费队列时才从磁盘中读取,但是性能会差一些。
05-RabbitMQ-高可用机制
一般来说,在生产的环境下,提到高可用机制,就不得不提集群了。
1、普通集群(标准集群)
2、镜像集群
有点像循环备份,保证了高可用性。
但是它存在一个问题:即主节点还没有给镜像节点备份就宕机了,这时候消息就丢失了。
3、仲裁队列
主从同步采用Raft协议,保持了数据的强一致性。
quorum参数使用仲裁队列