在 MessageDrivenBean 中为重新传递的消息指定 DeadLetterQueue

Specify DeadLetterQueue for redelivered messages in MessageDrivenBean

我创建了一个从 ActiveMQ 读取消息的 MDB

@MessageDriven(name = "MessageReaderEJB",
    activationConfig = {
            @ActivationConfigProperty(propertyName = "acknowledgeMode",
                    propertyValue = "Auto-acknowledge"),
            @ActivationConfigProperty(propertyName = "destinationType",
                    propertyValue = "javax.jms.Queue"),
            @ActivationConfigProperty(propertyName = "destination",
                    propertyValue = "archive.>")

    })

@Slf4j
public class ArchiveMessageListenerBean implements MessageListener {
   ...
   @Override
   public void onMessage(Message inMessage) {
   ...
   }
   ...
}

和我的 glassfish-ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish 
Application Server 3.1 EJB 3.1//EN"
    "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
<enterprise-beans>
    <ejb>
        <ejb-name>MessageReaderEJB</ejb-name>
        <mdb-connection-factory>
            <jndi-name>jms/jms.connectionFactory</jndi-name>
        </mdb-connection-factory>
        <mdb-resource-adapter>
            <resource-adapter-mid>ActiveMQ-Resource-Adapter-5.14.1</resource-adapter-mid>
        </mdb-resource-adapter>

    </ejb>
</enterprise-beans>
</glassfish-ejb-jar>

如果在 onMessage() 中抛出异常,则有一些重新传递并且在最大值之后。重新投递消息将发送到 ActiveMQ.DLQ。 如何配置将消息发送到 my.error.queue 而不是 ActiveMQ.DLQ?

感谢帮助!

您只能为给定的队列或主题指定特定的死信队列前缀。 如果您想根据 JMSDestination 消息头将消息从 DLQ 路由到另一个消息,则可以使用 Camel。

The broker transmits the default delivery policy that he prefers to a client connection in his BrokerInfo command packet. But the client can override the policy settings by using the ActiveMQConnection.getRedeliveryPolicy() method:

RedeliveryPolicy policy = connection.getRedeliveryPolicy();
policy.setInitialRedeliveryDelay(500);
policy.setBackOffMultiplier(2);
policy.setUseExponentialBackOff(true);
policy.setMaximumRedeliveries(2);

Once a message's redelivery attempts exceeds the maximumRedeliveries configured for the Redelivery Policy, a "Poison ACK" is sent back to the broker letting him know that the message was considered a poison pill. The Broker then takes the message and sends it to a Dead Letter Queue so that it can be analyzed later on.

The default Dead Letter Queue in ActiveMQ is called ActiveMQ.DLQ; all un-deliverable messages will get sent to this queue and this can be difficult to manage. So, you can set an individualDeadLetterStrategy in the destination policy map of the activemq.xml configuration file, which allows you to specify a specific dead letter queue prefix for a given queue or topic. You can apply this strategy using wild card if you like so that all queues get their own dead-letter queue, as is shown in the example below.

<broker>
     <destinationPolicy>
        <policyMap>
          <policyEntries>
            <policyEntry queue=">">
              <deadLetterStrategy>
                   <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
              </deadLetterStrategy>
            </policyEntry>
          </policyEntries>
        </policyMap>
    </destinationPolicy>
</broker> 

See the Redelivery Policy section for some more detail on the policy options.

http://activemq.apache.org/message-redelivery-and-dlq-handling.html