MQ使用场景:
1 异步发送,例如支付后,异步将结果通知其他系统。
2 销峰填谷
怎么保证消息不丢失呢?
来看看rabbitMQ消息发送过程
即发送者 -》 交换机 -》 队列 -》 消费者
丢失消息怎么办呢,分情况解决?
1 生产者发送消息没有到达队列。
rabbitMQ提供了publisher confirm(生产者确认)机制避免消息发送到MQ丢失,即消息发送到MQ后会返回一个结果给发送者,表示消息是否处理成功。 后续处理:既然知道了哪个消息发送失败,就可以调用回调方法即时重发。如果还失败,可以记录到日志中,通过查看日志进行补偿。最后还可以保存到数据库定时重发,成功发送后即删除表中数据。
最后不行,只能人工干预。
2 消息正常到达队列,MQ宕机怎么办?
消息持久化,MQ默认是内存管理消息,开启持久化功能确保缓存在MQ中的消息不丢失。 分别持久化交换机、队列、消息
3 消费者挂了呢?
rabbitMQ支持消费者确认机制,即消费者处理消息后可以向MQ发送ack回执。MQ收到回执后删除消息。 可以通过auto模式自动ack,即由spring监测listener代码是否由异常,没有异常返回ack,有异常返回nack.
消费者接收消息失败呢? 利用Spring的retry机制,当消费者出现异常进行重试,设置重试次数,达到后,依然失败就将消息投递到异常交换机由人工处理。
丢失重复消费怎么办?
如果消费者成功消费了消息,但是由于各种原因没有返回结果给MQ, 导致MQ进行重试,怎么办?
给每条消息设置唯一的标识ID,例如支付ID,订单ID等, 当消费者接收消息后校验该ID是否存在,如果已经存在,表面该消息已经消费,不需要再消费。
死信交换机或延迟队列是什么?
延迟队列:进入队列的消息会被延迟消费的队列 场景:超时订单,限时优惠,定时发布
延迟队列 = 死信交换机+ttl(生存时间)
什么是死信?
1 消费者声明消费失败或拒绝消费,且消息的requeue参数设置是false
2 过期消息,超时无人消费。
3 队列堆积满了。最早的消息成为死信。
如何处理死信呢?可以将其投递到死信交换机中。再转发到新的队列中,这样就可以重新被消费了。
如果一个消息超过 ttl 仍然没有被消费,就会变成死信,就会到死信交换机中,到绑定了死信交换机的队列中。
消息堆积怎么解决(假如一百万消息堆积在MQ怎么解决)?
什么情况下产生堆积? 当生产者发送速度超过消费者消费速度,就会导致队列中消息堆积。直到队列中消息达到上限,之后的消息成为死信,可能被丢弃。怎么解决呢?
1 增加更多消费者,提高消费速度, 2 消费者开启线程池,加快处理速度 3 扩大队列容积,提高上限
惰性队列设置
.lazy()
接收消息直接存磁盘而非内存,消费时从磁盘读取到内存,支持数百万消息存储。这样数量上增大,但是受限于磁盘IO,效率低了