DLQ-死信隊列(Dead Letter Queue)用來保存處理失敗或者過期的消息。
出現以下情況時,消息會被redelivered
- A transacted session is used and rollback() is called.
- A transacted session is closed before commit is called.
- A session is using CLIENT_ACKNOWLEDGE and Session.recover() is called.
當一個消息被redelivered超過maximumRedeliveries(缺省為6次,具體設置請參考后面的鏈接)次數時,會給broker發送一個"Poison ack",這個消息被認為是a poison pill,這時broker會將這個消息發送到DLQ,以便后續處理。
缺省的死信隊列是ActiveMQ.DLQ,如果沒有特別指定,死信都會被發送到這個隊列。
缺省持久消息過期,會被送到DLQ,非持久消息不會送到DLQ
可以通過配置文件(activemq.xml)來調整死信發送策略。
1. 不使用缺省的死信隊列
缺省所有隊列的死信消息都被發送到同一個缺省死信隊列,不便於管理。可以通過individualDeadLetterStrategy或sharedDeadLetterStrategy策略來進行修改。如下:
<broker...>
<destinationPolicy>
<policyMap>
<policyEntries>
<!— 設置所有隊列,使用 '>' ,否則用隊列名稱 -->
<policyEntry queue=">">
<deadLetterStrategy>
<!--
queuePrefix:設置死信隊列前綴
useQueueForQueueMessages: 設置使用隊列保存死信,還可以設置useQueueForTopicMessages,使用Topic來保存死信
-->
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" />
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
...
</broker>
2. 非持久消息保存到死信隊列
<policyEntry queue=">">
<deadLetterStrategy>
<sharedDeadLetterStrategy processNonPersistent="true" />
</deadLetterStrategy>
</policyEntry>
3. 過期消息不保存到死信隊列
<policyEntry queue=">">
<deadLetterStrategy>
<sharedDeadLetterStrategy processExpired="false" />
</deadLetterStrategy>
</policyEntry>
4. 持久消息不保存到死信隊列
對於過期的,可以通過processExpired屬性來控制,對於redelivered的失敗的消息,需要通過插件來實現如下:
丟棄所有死信
<beans>
<broker ...>
<plugins>
<discardingDLQBrokerPlugin dropAll="true" dropTemporaryTopics="true" dropTemporaryQueues="true" />
</plugins>
</broker>
</beans>
丟棄指定目的死信
<beans>
<broker ...>
<plugins>
<discardingDLQBrokerPlugin dropOnly="MY.EXAMPLE.TOPIC.29 MY.EXAMPLE.QUEUE.87" reportInterval="1000" />
</plugins>
</broker>
</beans>
注意,目的名稱使用空格分隔
The reportInterval property is used to denote how frequently do we output how many messages we have dropped - use 0 to disable.
用正則表達式過濾丟棄消息:
<beans>
<broker ...>
<plugins>
<discardingDLQBrokerPlugin dropOnly="MY.EXAMPLE.TOPIC.[0-9]{3} MY.EXAMPLE.QUEUE.[0-9]{3}" reportInterval="3000" />
</plugins>
</broker>
</beans>
Notice that the destination names use regular expressions. These match the number 000..999 at the end of each destination name.
5. 死信隊列消息的屬性
死信隊列中的消息,會增加幾個屬性,比如原過期時間(originalExpiration),原originalDeliveryMode等