这一次,rabbitMQ,还拿捏不住你?

71 阅读3分钟

MQ使用场景:

1 异步发送,例如支付后,异步将结果通知其他系统。

2 销峰填谷

怎么保证消息不丢失呢?

来看看rabbitMQ消息发送过程

image.png

即发送者 -》 交换机 -》 队列 -》 消费者

丢失消息怎么办呢,分情况解决?

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,效率低了