ACTIVEMQ的高级特性
- 异步投递
- 延时投递和定时投递
- 消息消費的重试机制
- 死信队列DLQ
- 消息不被重复消費,幂等性
1.异步投递
官网介绍:ActiveMQ官网异步投递
ActiveMQ支持以同步或异步模式将消息发送到broker。使用的模式对发送呼叫的延迟有很大的影响。由于延迟通常是生产者可以实现的吞吐量的重要因素,因此使用异步发送可以显着提高系统的性能。
ActiveMQ在某些情况下默认情况下以异步模式发送消息。仅在JMS规范要求使用同步发送和没有使用事务发送持久化消息的情况下,我们才默认使用同步发送。
如果您不使用事务并正在发送持久消息,则每次发送都将同步并阻塞,直到broker向producer发送回确认消息已将消息安全地持久保存到磁盘为止。该ACK保证了消息不会丢失,但是由于客户端被阻止,因此还付出了巨大的等待时间。
许多高性能应用程序旨在承受故障情况下的少量消息丢失。如果您的应用程序是按照这种方式设计的,则即使使用持久性消息,也可以启用异步发送来提高吞吐量。
这里是指的异步:producer和broker之间,不是producer和customer
异步发送
它可以提高producer的发送效率。我认为在消息比较密集的时候使用异步发送 但是这样带来了一些问题:
- 消息并不能保证发送成功,在useAsyncSend=true 的情况下客户端需要忍受消息丢失的可能。
- 消耗较多的Client端的内存同时也会导致broker的性能的损耗。
代码的实现
代码案例
异步确认消息发送成功
异步发送丢失消息的场景是:producer设置useAsycSend=true,使用producer.send(msg)持续发送消息
由于消息不阻塞,生产者都会认为消息已经成功发送过去。
但是如果 MQ突然宕机,次是producer中内存中尚未发送至MQ的消息都会丢失,所以正确的异步发送
是需要接收回调
同步发送和异步发送的区别
1.同步发送:send不阻塞了就表示一定发送成功
2.异步发送需要接受执行,并由客户端在判断一次是否成功
代码的案例
2.延时投递和定时发送
官网:定时发送
四大属性
操作配置
代码的实现,要知道之前的四个属性
这里消费者和之前的一样!!!
3.消息消費的重试机制
什么时重试机制
官网:重试机制
customer收到消息之后,出现异常,未能把确认消息发送给broker 则 broker会持续的发送之前消息给broker。尝试n次之后,如果customer还没有回复消息,则将消息放置到 死信队列,之后broker就不会在发送消息
那些情况引发
- Client用了事务,且在session中调用了rollback
- Client用了事务,且在用commit之前关闭 或者没有commit
- Client再Client_ACKNOWKEDGE的传递模式下,session中调用了recover
重发的时间间隔和次数
- 间隔:1
- 次数:6
- 每秒发:6次
有毒的消息,Posion ACK
一个消息如果redelivered 超过默认次数(6),Customer 会回复broker一个Posion ACK 的消息,告诉broker不要再发送了。这时broker会将消息放到DLQ(死信队列)
属性说明
代码验证
producer 发送三条消息,代码和之前的一样
customer 将 commit 注释掉
接收了6次之后,第7次 就不会再接收到消息
修改默认参数
整合Spring
4.死信队列
死信队列:异常消息规避处理的集合,主要处理失败的消息。
一般生产环境
一般生产环境下是:一个是核心业务队列,一个是死信队列
死信队列可以用来处理 异常消息。
私信队列的配置
- sharedDeadLetterStrategy
不管是queue还是topic,失败的消息都放到这个队列中。下面修改activemq.xml的配置,可以达到修改队列的名字。
- individualDeadLetterStrategy
可以为queue和topic单独指定两个死信队列。还可以为某个话题,单独指定一个死信队列。
这里 useQueueForTopicMessages 中false: 是Topic| true:Queue
配置案例
自动删除过期消息*
过期消息是指:producer 指定的过期时间,超过这个时间的消息。
5.消息不被重复消费,幂等性
如何保证消息不被重复消费?幂等性问题你来谈谈
网络延迟传输,会造成MQ 重试,在重试过程中,可能会造成重复消费问题
在数据库中:给消息一个唯一的主键,那么就算出现重复消费的情况,就会导致主键冲突,避免出现脏数据
利用redis:给消息分配一个全局ID,只要消费过该消息,将<id,message>以K-V的形式保存在redis中去,那么消费者开始消费的时候,先去redis中查询是否有消费记录。