MQ基础:
mq的5种工作模式
mq的好处和缺点
好处:异步,削峰,解耦
缺点:实时性,复杂性,高可用性
MQ高级
幂等性(try lock),消息丢失,消息堆积,消息高可用性,延迟消息问题
消息丢失的情况
真实情况蓝色箭头的每一步可能产生消息丢失的问题。
消息的可靠性
- 消息丢失的情况:
- 发送时丢失,生产者发送消息未送达exchange
- 消息到达exchange(交换机)后未达到Queue(队列)
- MQ宕机,Queue将消息丢失
- consumer接收消息后未消费就宕机
生产者确认机制:
RabbitMQ提供了publisher confirm的机制来避免消息发送到MQ过程中丢失。消息发送以后,会返回一个结果给发送者表示消费信息处理成功。结果由两种请求。
- publisher-confirm,发送者确认:
- 消息成功投递到交换机,返回ack
- 消息未投递到交换机,返回 nack
- publisher-retrn,发送者回执
消息投递到交换机,但是没有路由到队列。返回ack,及路由失败的原因。
消息持久化
消费者确认机制
RabbitMQ支持消费者确认机制,即消费者处理消息以后可以向MQ发起ack回执,MQ收到ACK回执后才会删除消息.
但是如果在消费在处理消息的过程中抛出异常,就应该返回NACK,生产者就应该重新投递消息。或者消费者直接挂了,ack和nack都没有发给生产者,生产者就真的会认为他挂了,会等待消费者重新上线提供服务继续发送消息。
而SpringAMQP支持三种 确认模式
- manual:手动ack,需要在业务结束后,调用api发送ack,由侵入性
- auto : 自动ack,由spring检测listener代码是否出现异常,没有异常返回ack,出现异常相应nack。
- none:关闭ack,MQ假定消费者获取消息后会成功处理,一次消息投递后会立即被删除。
消费者重试机制
当消费者出现异常以后,消息会不断requeue(重新入队)到队列,再重新发送给消费者,然后再次异常,再次热queue,无限循环,导致mq的消息处理飙升,带来不必要的压力。
为了使消费者出现异常之后不再requeue,在spring中可以设置一个重试机制,让出现异常,先让该队列消息在本地进行重试,未达到重试次数成功,就再丢回消息队列,如果失败就抛出异常。
消费者失败消息处理策略
再开启此时后,重试次数好久,如果消息依然失败,则需要由MessageRecover接口来处理,他有三种不同的实现。
- RejectAndDontRequeueRecoverer:重试耗尽后,直接reject,丢弃消息。默认就是这种方式。
- ImmediateRequeueMessageRecoverer:重试耗尽以后,返回back,消息重新入队
- RepublishMessageRecoveerer:重试耗尽由,将失败消息投递到指导的交换机。
如何确保RabbitMQ消息的可靠性?
- 开启生产者确认资质,确保圣餐在的消息能到达队列
- 开启持久化功能,确认消息未消费前在队列中不会丢失
- 开启消费者确认机制为auto,由spring确认消息处理成功后完成ACK
- 开启消费者失败重试机制,设置MEssageRecoverer,多次重试失败后将消息都睇到异常交换机,交由人工处理。
消息死信交换机
当一个队列的消息满足下列情况之一,可以成为死信交换机
- 消费者使用basic.reject或者basic.nack生命消费失败,并且消息的rerqueue参数设置为false
- 消息是一个过期消息,超时无人消费
- 要是投递消息的队列满了,最早的消息可能成为死信就会投递到中国交换机中,这个交换机成为死信交换机简称DLX
TTL
TTL,就是Time-To-Live。如果一个队列中的消息TTL借宿任未消费,就会变成死信,ttl超时有两种情况
- 消息所在的队列设置了存活时间
- 消息本省设置了存活时间。
延迟队列
利用TTL结合死信交换机,莫问是新了发送消息,消费者安驰收到的效果。这个消息模式为延迟队列。b
消息堆积
生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,指导队列存储消息达到上线。最早接收到的消息,可能会成为死信,会被丢弃,这就是消息堆积问题。
- 解决方法:
增加更多的消费者,提高消费速度
消费者内开启线程池加快消息处理速度
扩大队列溶剂,提高堆积上限。
惰性队列
惰性队列的特征:
- 接收到消息后直接存入磁盘而非内存
- 消费者要消费消息的时候才亏从磁盘读取并加载到内存
- 支持数百万条的消息存储。
惰性队列的优点:基于磁盘存储,消息上限高
没有间歇性page-out,性能比较稳定
惰性队列的缺点:
基于次哦按存储,消息时效性会降低
性能受限于磁盘io
MQ集群
集群分类:
-
普通集群:一种分布式群,将队列分散到集群的各个节点,从而提高整个集群的并发能力。
对集群的和各个节点间共享部分数据,包括:交换队列消息。不包括队列中的消息。 -
镜像集群:一种蛀虫集群,普通集群的基础上,添加主从备份功能,提高集群的数据可用性。
- 交换机,队列,队列中的消息会在各个mq的进项节点之间同步备份。
- 创建队列的节点被称为该队列的主节点,被分到其他节点叫做该队列的镜像节点。
- 一个队列的主节点可能1是另外一个队列的镜像节
- 所有操作都在主节点完成,然后同步给镜像节点
- 住系欸但宕机后,镜像系欸但会代替成为新的主节点。
- 仲裁节点:
镜像集群对人支持主从,丢失主从同步并不是强一致,某些情况下可能会有数据丢失的风险。因此在RabbitMQ3.8版本以后,推出了新的功能:仲裁队列来代替镜像集群,底层采用Raft协议确保主从的数据一致性。
-
与镜像节点一样,都是主从模式,支持主从数据同步
-
使用非常简单, 没有复杂的配置
-
主从同步基于Raft协议,强一致。
-
项目如何使用MQ?(使用MQ解决什么问题,又带来了什么问题)