1.引入消息队列之后该如何保证其高可用性
持久化、事务、签收、集群。
2.异步投递Async Sends,异步发送如何确认发送成功?
异步发送丢失消息的场景是:生产者设置UserAsyncSend=true,使用producer.send(msg)持续发送消息。由于消息不阻塞,生产者会认为所有send的消息均被成功发送至MQ. 如果MQ突然宕机,此时生产者端内存中尚未被发送至MQ的消息都会丢失,所以,正确的异步方式发送是需要接收回调的。
同步发送和异步发送的区别就在此,同步发送等send不阻塞了就表示一定发送成功了,异步发送需要接收回执并由客户端再判断一次是否发送成功。
3.延迟投递和定时投递
在activemq.xml配置文件里面的broker里面设置一个属性schedulerSupport=true,然后4大属性
4.消费重试机制
具体哪些情况会引起消息重发
1.Client用了transactions且在session中调用了rollback()
2.Client用了transactions且在调用commit()之前关闭或者没有commit
3.Client在CLIENT_ACKNOWLEDGE的传递模式下,在session中调用了recover()
消息重发时间间隔和重发次数
间隔1 ,次数6
有毒消息Poison ACK 谈谈你的理解
一个消息被redelivedred超过默认的最大重发次数(默认6次)时,消费端会给MQ发送一个“poison ack”表示这个消息有毒,告诉broker不要再发了,这个时候broker会把这消息放到DLQ(死信队列)
5.死信队列
处理失败的消息
配置案列
1.自动删除过期消息
2.存放非持久消息到死信队列中。
如何保证消息不被重复消费,幂等性检查
网络延迟传输中,会造成进行MQ重试中,在重试过程中,可能会造成重复消费。
1.如果消息是做数据库的插入操作,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。
2.准备一个第三方服务方来做消费记录,以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以k-v形式写入redis,那消费者开始消费前,先去redis中查询有没消费记录即可。