1.消息的可靠性
1.1.什么是可靠性?
消息由生产者产生发送到MQ,最终被消费者正常消费。
1.2.消息丢失的几种情况?
生产者连不上MQ
- 因为网络不可靠,导致生产者暂时连不上MQ。(生产者开启重试策略)
生产者发送消息未到达交换机
- 开启confirm回调机制,每个生产者独立配置。到达交换机返回ack,没到交换机返回nack。
消息到达交换机,没有正确路由到队列
- 开启return回调机制,消息没到队列会被回调。
MQ宕机队列中的消息不见了
消费者收到消息,还没消费,消费者宕机
- 开启自动ack,并且设置本地重试策略,当本地重试次数耗尽后,失败消息路由到错误队列。
1.3.如何保证消息不丢失
生产者确认机制
-
publisher-confirm
- 消息成功投递到交换机,返回ack。
- 消息未成功投递到交换机,返回nack。记录消息以及交换机等相关信息到数据库,后期可以编写任务去补偿发送
-
publisher-return
- 未正确到达队列,返回ack及失败原因。记录消息以及交换机等相关信息到数据库,后期可以编写任务去补偿发送。
持久化机制
-
交换机持久化
- 默认就是持久化,durable默认就是true
-
队列持久化
- 默认就是持久化,durable默认就是true
-
消息持久化
- 在发送消息时,使用Message对象,并设置delivery-mode为持久化
- 默认就是持久化
消费者ack机制
-
none:只要消息到达消费者,消费者直接返回ack给MQ
-
manual:手动ack
- 消费成功,调用API给MQ返回ack
- 消费失败,调用API给MQ返回nack,并且让消息重回队列
-
auto:自动ack。消费消息不出异常,返回ack给MQ。消费消息出异常了,返回nack,把消息重回队列
-
本地重试:达到重试次数后,还是失败,则返回ack,不requeue。MQ会删除队列消息
-
失败策略
- RejectAndDontRequeueRecoverer:重试耗尽后,直接reject,丢弃消息。默认就是这种方式
- ImmediateRequeueMessageRecoverer:重试耗尽后,返回nack,消息重新入队
- RepublishMessageRecoverer:重试耗尽后,将失败消息投递到指定的交换机
-
使用 RepublishMessageRecoverer
- 定义错误交换机、队列、绑定关系。定义RepublishMessageRecoverer
- 监听错误队列
-
2.MQ如何保证消息可靠性?如何保证消息不丢失?
生产者
- 开启重试策略,保证消息正确到达MQ,如果重试次数耗尽,则写入数据库,后期交由人工处理
- 开启confirm机制,保证消息正确到达交换机
- 开启return机制,保证消息正确到达队列
持久化操作
- 创建交换机、队列、消息时设置持久化(默认就是持久化),保证MQ宕机后重启不丢失
消费者
- 开启自动ack,并且设置本地重试策略,当本地重试次数耗尽后,失败消息路由到错误队列。
- 监听错误队列,把消息写入数据库,后期交由人工处理