摘要:该文章主要针对ActiveMQ高级特性中的死信队列进行相关的介绍和说明,由于目前网上相关知识的介绍有所欠缺,因此本文着重介绍在activemq.xml中对死信队列的相关策略进行配置时的属性说明。
死信队列
一、死信队列的由来
1. 什么是死信队列
在ActiveMQ中,正常情况下,broker给消费者发送消息,消费者顺利消费完消息后,消息会离开queue或topic。但在几种特殊情况下,broker虽然给消费者发送了消息,但消费者消费异常,导致消息没能顺利离开broker,此时broker会对本次消费异常的消息进行重新发送给消费者,以便重新进行正常的消费,此机制为消息的重发机制。
消息重发,默认最多重发6次,当某一个消息被broker重发6次后仍无法正常被消费者消费,就会被broker标记为poisoned pill(即有毒信息),并且broker不会再对该消息进行重新发送,而是将其投递到死信队列(即DLQ:Dead Letter Queue)中。
2. 消息会重新投递给消费者的几种情况
当发生以下任何情况时,消息将重新传递给消费者客户端:
- 使用并 rollback()调用事务处理会话。
- 事务会话在 commit()被调用之前关闭。
- 会话正在使用 CLIENT_ACKNOWLEDGE并被 Session.recover()调用。
- 客户端连接超时(可能正在执行的代码比配置的超时时间长)。
二、死信队列的配置属性说明
1. 共享死信队列(sharedDeadLetterStrategy标签)
在该死信管理策略下,无论是queue还是topic,失败的消息都放到这个队列中。
2. 独立死信队列(individualDeadLetterStrategy标签)
为了防止混淆,我们把收集管理有毒信息(即死信)的位置称为死信目的地。默认情况下,queue和topic中的有毒信息,都会被送往名为ActiveMQ.DLQ的死信队列中,该死信队列的类型为queue。
我们可以通过在activemq.xml配置文件中修改配置,从而改变queue或topic的死信目的地类型和死信目的地名称。
(1). topicPrefix属性 和 queuePrefix属性
对于Queue而言,死信目的地的默认前缀为“ActiveMQ.DLQ.Queue”,可以通过修改individualDeadLetterStrategy标签中的queuePrefix属性来修改Queue的死信目的地前缀。
对于Topic而言,死信目的地的默认前缀为“ActiveMQ.DLQ.Topic”,可以通过修改individualDeadLetterStrategy标签中的topicPrefix属性来修改Topic的死信目的地前缀。
注意,Queue只能使用queuePrefix属性修改,Topic只能使用topicPrefix属性修改,不能混用,否则不起作用。
(2). useQueueForQueueMessages属性 和 useQueueForTopicMessages属性
由于queue和topic的死信目的地,默认情况下都是ActiveMQ.DQL,因此默认情况下都是queue类型。
对于Queue,可以在individualDeadLetterStrategy标签中设置属性useQueueForQueueMessages决定Queue的死信目的地类型,当useQueueForQueueMessages=true表示死信目的地为queue类型,当=false表示死信目的地为topic类型。
对于Topic,可以在individualDeadLetterStrategy标签中设置属性useQueueForTopicMessages决定Topic的死信目的地类型,当useQueueForTopicMessages=true表示死信目的地为queue类型,当=false表示死信目的地为topic类型。
以下是修改activemq.xml配置文件的案例:
该案例的相关属性配置说明如下:
- queue=”> ”是通配符写法,代表mq中的所有的queue都生效,类似于SQL中的” * ”。也可以指定某一个具体的queue的名称,则该死信配置策略是对某一具体的queue有效。
- 在此配置下,mq中的所有queue的死信目的地都为topic类型,每个queue都有自己的死信目的地,死信目的地的名称是前缀"DLQ." + queue名称。
- 在此配置下,mq中名为mq_senior_topic_DQL_test的topic的死信目的地是queue类型,死信目的地的名称是前缀“TopicDLQ.” + topic名称,即为TopicDLQ.mq_senior_topic_DQL_test。其他的topic的死信目的地都是系统默认策略,即统一将死信送往名为ActiveMQ.DLQ的死信队列中。
好了,以上就是我个人对本次内容的理解与解析,如果有什么不恰当的地方,还望各位兄弟在评论区指出哦。
如果这篇文章对你有帮助的话,不妨点个关注吧~
期待下次我们共同讨论,一起进步~