如何解决消费可靠性问题?

成功发送示例是:成功收到Confirm的ack,没收到Callback的ack。
答:生产者确认机制,上图所示。生产者通过Confirm机制发送消息,问交换机收到没?收到就返回ack,没收到返回nack。交换机将消息发送给队列也是如此,没收到你就返回个ack。
如何解决MQ消息持久化?
MQ持久化:队列,交换机,消息持久化,使用springAMQP框架里面默认实现持久化。
消费者确认
springAMQP允许三种确认模式
manual:手动ack,需要在业务代码结束后,调用aoi发送ack
auto:自动ack,由spring监测listener代码是否出现异常,没有异常返回ack,抛出异常。推荐使用
无需确认机制:即生产者将消息发送到队列,消费者监听到该消息是,无需发送任何反馈信息给RabbitMQ 服务器
关于消费者auto出现异常后,消息不断requeue重新到队列,在重新发送给消费者,然后再次异常,又再次不断requeue,无限循环,导致mq的消息处理飙升,带来不必要压力。
解决方法:
设置本地重试策略


消费者消息失败策略

保证消息不丢失:开启ack自动重试,在本地设置重试提交策列,加入一个错误交换机用来路由提交失败的消息并转发到接收失败消息的队列写入到磁盘当中。

死信与死信交换机
什么消息会成为死信?
答:有三种情况,一,消息被消费者reject或者返回nack(被丢弃)。二,消息超时未消费TTL(基于该消息是被设置了TTL属性,延迟消息设置两种,第一种是消息所在队列设置了存货时间。第二种消息本身设置了存货时间)。
三,队列满了。
死信交换机
定义:就是接收路由死信的交换机,类似垃圾回收站。
工作原理图

当消息发送到队列超时未被消费者消费时,队列则会通过key找到与之对应的死信交换机,死信交换机路由转发给死信队列再给消费者消费。
集群

消息顺序性
举例:一个完整业务涉及到支付业务,订单业务,发货业务,如何保证消费者怎么保证这三个业务的消息顺序性(完整顺序流程是先支付,产生订单,根据订单进行发货),还能保证多消费者模式下高并发处理能力不会下降呢?

答:这个问题很好解决,使用Hash取模法来保证同一个订单在同一个队列中就行了,,然后该订单的所有消息都会被投放到这个队列中,因为每个业务的子业务之间的业务id是一样的,进行hash取模的值一定一致。
消息幂等性
定义:就是同一个业务被消费者重复消费。
如何预防消息被重复消费呢?
答:给每个消息指定一个全局唯一id,如果消费者拿到消息进行消费时会先判断是否之前消费过?(这里涉及到一个记录消费过的消息id,可以使用redis进行存储id),如果属于二手id则会抛弃。
