使用SpringJMS将自定义异常路由到ActiveMQ中的DLQ

使用SpringJMS将自定义异常路由到ActiveMQ中的DLQ,activemq,spring-jms,Activemq,Spring Jms,我正在使用代理activemq 5.5.1和SpringJMS进行消息传递。我有如下要求 A) 我只想在出现相应异常时将消息推入DLQ。目前据我所知,消息侦听器引发的任何异常都会在指定重试参数后移动到DLQ。ActiveMQ是否提供此功能以及如何提供 B) 我必须基于类级别控制重试机制,这意味着对自定义异常不进行重试。例如,如果抛出了MyException类的实例,我不应该重试这些消息,这样它就不应该转到DLQ。请告知 -----编辑----------- 当jmsrelived为true时,我

我正在使用代理activemq 5.5.1和SpringJMS进行消息传递。我有如下要求

A) 我只想在出现相应异常时将消息推入DLQ。目前据我所知,消息侦听器引发的任何异常都会在指定重试参数后移动到DLQ。ActiveMQ是否提供此功能以及如何提供

B) 我必须基于类级别控制重试机制,这意味着对自定义异常不进行重试。例如,如果抛出了MyException类的实例,我不应该重试这些消息,这样它就不应该转到DLQ。请告知

-----编辑-----------


当jmsrelived为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>
public-void-onMessage(消息消息){
试一试{
如果(消息!=null)
如果(文本消息的消息实例){
字符串messageContent=((TextMessage)message)。
if(message.getBooleanProperty(“jmsredelived”)){
抛出新的CustomException1();
}否则{
抛出新的CustomJMSException(“重试逻辑”);
}
}
}
}捕获(jmsex异常jmsex){
}捕获(自定义例外1 e){
System.out.println(“捕获异常”);
}捕获(自定义JME){
抛出新的CustomJMSException(“抛出异常”);
}
弹簧配置:

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

您只需捕获(并忽略或记录)即可要忽略的异常,并重新抛出要路由到DLQ的异常


或者,您可以使用代替activeMQ的机制;它具有确定应重试哪些异常的策略,以及允许您决定吸收或重新抛出哪些异常的
RecoveryCallback

我可以捕获不应移动到DLQ的异常,但是,请告诉我是否也将根据重新交付策略重试这些异常?如果是,除了spring retry(我将探讨)之外,我们是否可以用其他方式处理它。如果没有spring retry,您唯一可以做的就是一次重新交付尝试-测试
jmsredivered
头。如果您想在两次以上的尝试后忽略传递,则需要有状态的spring retry或其他机制来跟踪尝试次数。我测试了设置JMSRedelived标头,但是,一旦从侦听器抛出异常,就不会有控件返回。我需要在第二次尝试时停止重试。如果我的理解是错误的,或者如果您认为我的实现可能是错误的,请注意,如果
jmsrediver
true
,请捕获异常。当jmsrediver是true时,我尝试限制重试尝试。但是这个消息虽然只为重试抛出一次异常,但它并没有添加到DLQ。我还需要在DLQ中添加毒药消息。请告知。我已经在这里添加了测试代码