一、如何保证消息可靠性?
1、保证消息投递到MQ不丢:开启生产者消息确认机制
1)、开启ConfirmCallBack回调:消息投递至交换机的回调(成功、失败、异常)
2)、开启ReturnCallBack回调:消息从交换机未路由到队列的回调
2、保证消息到达MQ之后不丢(MQ宕机了也不影响):消息持久化(三者默认就是持久化的)
1)、交换机的持久化
2)、队列的持久化
3)、消息的持久化
3、保证消费者不丢(必须至少消费一次):开启消费者消息确认机制
1)、none:没有确认机制,如果出现异常也会直接丢弃
2)、manual:手动确认
1、可以自己灵活的控制消息的确认和拒收
2、注意:开启这个机制后一定要记得手动回执,否则将造成消息大量堆积问题
3)、auto:自动确认
优点:出现异常返回nack,正常执行返回ack,无需编写业务代码、无侵入(原理:AOP)
缺点:当消费消息出现异常返回nack时会一直反复投递,解决:开启消费者本地重试机制(有一个最大重试次数)
消费者重试机制:消息消费失败,消费者会自己发起重试,重试间隔和最大重试次数可灵活配置
当超过最大重试次数时,消费者对于消息会有几种执行策略:
1、直接丢弃:该消息从MQ删除(Reject) - 默认
2、放回队列:将消息放回至队列,然后投递给消费者,消费者进行重试,如此循环往复
3、投递至指定的交换机(常用):将消息投递至专用的交换机,绑定队列后进行精准消费
二、如何实现消息延时投递?
1、死信交换机:专门用于存放以下三类垃圾消息的交换机:
1)、被拒绝或者nack(false)的消息
2)、队列放不下的消息
3)、超时过期未被消费的消息(ttl)
2、利用【死信交换机+TTL】机制实现延时投递
原理:消息超时未被消费会被投递至死信队列
设置超时:
1、针对消息设置延时时间
2、针对队列设置延时时间
适用范围:
延时时长固定的业务,而不适用于延时时长不固定的业务,因为延时时长较长的消息如果在前面,就会阻塞后面延时时长较短的消息
怎么解决?使用交换机插件可以解决
3、利用延时交换机插件实现延时投递
原理:交换机基于内存存储消息,延时路由,到达指定时间会被路由至队列
缺点:可能会造成return callback的误判,所以我们在return callback的代码中进行了"修复"
三、如何解决消息堆积问题?
1、针对【同一业务消息】增加【多个队列】进行消息路由
2、针对【同一队列】增加【多个消费者】进行消息消费
3、针对【同一消费者】开启【多个线程】进行消息消费
4、加大队列的存储容量:惰性队列
1)、原理:直接将消息写到磁盘
2)、优点:存储容量大,减少从内存刷消息数据至磁盘的次数,性能更稳定
3)、缺点:性能取决于磁盘IO