ActiveMQ消息投递方式+死信队列
死信队列
死信队列(Dead Letter Queue,DLQ),用来保存处理失败或者过期的信息。出现以下情况的时候,消息会被重发:
- 在一个事务session中调用了session.rollback()方法。
- 在一个事务session中,session.commit()之前调用了commit.close()。
- 在session中使用CLIENT_ACKNOWLEDGE签收模式,并且调用了session.recover()方法。
- 在非事务session中使用INDIVIDUAL_ACKNOWLEDGE签收模式,并且调用了session.recover()方法。
在session中使用AUTO_ACKNOWLEDGE签收模式,在异步(messageListener)消费消息情况下,如果onMessage方法异常且没有被catch,此消息会被redelivery。
当一个消息被重发次数超过设置的最大重发次数(缺省为6)时,会给broker发送一个“poison ack”,此消息被认为是a poison pill,这时broker会将这个消息发送到死信队列,以便后续处理。注意两点:
1. 缺省持久消息过期,会被送到DLQ,非持久消息不会送到DLQ。
2. 默认的死信队列是ActiveMQ.DLQ,如果没有特别指定,死信都会被发送到这个队列中。
可以通过配置文件activemq.xml来调整死信发送策略。在浏览器地址栏输入 http://localhost:8161/admin ,打开ActiveMQ的管理界面,可以看到私信队列数量:
从控制面板可知,死信队列默认名为ActiveMQ.DLQ,其数量为20条。顺便介绍一下控制面板各个表头的含义:
- Number Of Consumers:消费者数量;
- Number Of Pending Messages:等待消费的消息数量,这个是当前未出队列的数量;
- Messages Enqueued:进入队列的消息量,它只增不减,重启后会清零;
- Messages Dequeued:被消费的消息量,重启后会清零。
如果设置了消息的持久化,那么重启前没有被消费的消息会在Number Of Pending Messages中显示。
配置死信队列
在activemq.xml中,为队列【east7-queue】配置独立的死信队列,下面是queue和topic两种形式,我选择点对点模式queue,新增配置信息字体为红色:
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">">
<deadLetterStrategy>
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
</deadLetterStrategy>
</policyEntry>
<policyEntry topic=">" >
<!-- The constantPendingMessageLimitStrategy is used to prevent
slow topic consumers to block producers and affect other consumers
by limiting the number of messages that are retained
For more information, see:
http://activemq.apache.org/slow-consumer-handling.html
-->
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
- queuePrefix:设置死信队列前缀。
- useQueueForQueueMessages: 设置使用队列保存死信,还可以设置useQueueForTopicMessages,使用Topic来保存死信。
使用<policyEntry queue="east7-queue">指定待创建死信队列的队列为DLQ.east7-queue,其它的队列的死信队列使用队列名。如下图所示,myDest.queue私信队列中消息数量为3。如果<policyEntry queue=">">,则是为所有点对点模式队列创建DLQ.+队列名的死信队列。
还有其他策略,这个要根据实际情况来对应处理。比如:非持久消息保存到死信队列
1 <policyEntry queue=">"> 2 <deadLetterStrategy> 3 <sharedDeadLetterStrategy processNonPersistent="true" /> 4 </deadLetterStrategy> 5 </policyEntry>
过期消息不保存到死信队列:
1 <policyEntry queue=">"> 2 <deadLetterStrategy> 3 <sharedDeadLetterStrategy processExpired="false" /> 4 </deadLetterStrategy> 5 </policyEntry>
关于本文内容,大家有什么看法?欢迎留言讨论,也希望大家多多点赞关注。祝各位生活愉快!工作顺利!
![](https://common.cnblogs.com/images/wechat.png)