自定义异常使用Spring JMS在ActiveMQ中路由到DLQ

时间:2014-11-27 09:29:22

标签: activemq spring-jms

我使用broker activemq 5.5.1和Spring JMS进行消息传递。我的要求如下

A)我想只在发生相应的异常时才将消息推送到DLQ。目前根据我的理解,在指定的重试参数之后,从消息侦听器抛出的任何异常都会移动到DLQ。 ActiveMQ是否提供此功能以及如何使用?

B)我必须根据类级别控制重试机制,这意味着自定义异常的No-Retry。例如,如果抛出了一个MyException类实例,我不应该重试这些消息,以免它转到DLQ。请指教

----- EDIT -----------

当JMSRedelivered为true时,我尝试限制重试尝试。但是这个消息虽然异常只被抛出一次才重试,但是没有添加到DLQ。这是我的测试代码。我正在使用activemq 5.5.1

 public void onMessage(Message message) {
    try {
        if (message != null)
            if (message instanceof TextMessage) {
                String messageContent = ((TextMessage) message).
                if (message.getBooleanProperty("JMSRedelivered")) {
                    throw new CustomException1();
                } else {
                    throw new CustomJMSException("Retry Logic");
                }
            }
        }
    } catch (JMSException jmsex) {

    } catch (CustomException1 e) {
        System.out.println("Exception Caught");
    } catch (CustomJMSException e) {
        throw new CustomJMSException("Exception thrown");
    }


Spring Configuration:

<bean id="redeliveryPolicy1" class="org.apache.activemq.RedeliveryPolicy">
    <property name="initialRedeliveryDelay" value="1000" />
    <property name="redeliveryDelay" value="1000" /> 
    <property name="maximumRedeliveries" value="5" />
    <property name="useExponentialBackOff" value="false" />
    <property name="backOffMultiplier" value="1" /> 
</bean>

2 个答案:

答案 0 :(得分:1)

答案1)是ActiveMQ具有开箱即用功能,其中失败的消息(在某​​些重试之后)会自动移动到名为ActiveMQ.DLQ的队列,这是代理中所有队列的默认死信队列

答案 1 :(得分:1)

您需要做的就是捕获(并忽略或记录)您要忽略的异常,并重新抛出您想要路由到DLQ的异常。

或者,您可以使用spring-retry代替activeMQ的机制;它有确定应该重试哪些例外的政策,以及允许你决定吸收或重新抛出哪些例外的RecoveryCallback