消息确认的过程
ACK_MODE
前面已经说过,消息的确认有三种模式:
ACK_TYP
虽然 Client 端指定了 ACK 模式,但是在 Client 与 broker 在交换 ACK 指令的时候,还需要告知ACK_TYPE, ACK_TYPE 表示此确认指令的类型,不同的 ACK_TYPE 将传递着不同的消息的状态,broker 可以根据不同的ACK_TYPE 对消息进行不同的操作。
Client 端在不同的 ACK 模式时,将意味着在不同的时机发送 ACK 指令,每个 ACK 指令 中会包含 ACK_TYPE,那么broker 端就可以根据 ACK_TYPE 来决定此消息的后续操作。
消息重发
导致消息重新发送的场景:
在事务性会话中,没有调用 session.commit 确认消息或者调用了 session.rollback 方法回滚消息
在非事务性会话中,消息确认模式为 CLIENT_ACKNOWLEDGE 的情况下,没有调用 acknowledge 方法;
死信队列
一个消息被重发,超过默认的最大重发次数(默认6次)时,消费端会给 broker 发送一个”poison ack”,表示这个消息是不能处理的消息,告诉 broker不要再发了。这个时候 broker 会把这个消息放到DLQ(死信队列)。
ActiveMQ 中默认的死信队列是 ActiveMQ.DLQ,默认情况下,超过最大重发次数的消息或者持久化消息过期以后都会被发送到这个队列。
所有队列的死信消息都被默认发送到同一个默认的死信队列 ActiveMQ.DLQ,不便于后期的数据处理,可以通过配置文件(activemq.xml) 设置 individualDeadLetterStrategy 或 sharedDeadLetterStrategy 属性来调整死信的发送策略。
配置参考:
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- 使用 '>',表示对所有队列生效,如果需要设置指定队列,则直接写队列名称 -->
<policyEntry queue=">">
<deadLetterStrategy>
<!-- queuePrefix:设置死信队列前缀,useQueueForQueueMessages: 设置使用队列保存死信 -->
<individualDeadLetterStrategy
queuePrefix="DLQ." useQueueForQueueMessages="true" />
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>