集成Tomcat与ActiveMQ和Spring的DefaultMessageListenerContainer - 再次重新发送JMS消息

时间:2016-05-25 10:35:47

标签: tomcat activemq spring-integration spring-jms

我有以下设置: 嵌入式ActiveMQ的Tomcat

我使用Spring集成的JmsMessageDrivenChannelAdapter来创建适配器,该适配器使用来自ActiveMQ队列的消息,如下所示:

 Jms.messageDrivenChannelAdapter(jmsConnectionFactory, TransactedMessageListenerContainer.class)
      .destination(destination)
      .errorChannel(errorChannel)
     .get();

其中TransactedMessageListenerContainer是

public class TransactedMessageListenerContainer extends DefaultMessageListenerContainer {

     public TransactedMessageListenerContainer() {
         this.setSessionTransacted(true);
     } 
}

如果发生异常,ActiveMQ代理不会相应地重新发送消息。

当我使用org.apache.activemq.broker.BrokerService进行简单的集成测试时,会重新传递JMS消息,即我可以实现重试机制

如何使用ActiveMQ为Tomcat实现相同的目标?

我在这里找到:http://activemq.apache.org/tomcat.html,手动将ActiveMQ与Tomcat集成,允许注入Topic,Queue和ConnectionFactory,但不支持事务性发送和传递,但我不确定是否有一些解决方法

感谢您的帮助!

更新 我还在错误处理程序中重新抛出异常,如下所示:

@Bean
public IntegrationFlow errorHandlingFlow() {
    return IntegrationFlows.from(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
             .handle(this::errorMessageHandler)
             .get();
}

public void errorMessageHandler(Message<?> message) {
    log.warn("handling error message");
    log.warn("headers: " + message.getHeaders().toString());
    log.warn("payload: " + message.getPayload().toString());
    MessagingException exception = (MessagingException) message.getPayload();
    log.warn("original payload: " + exception.getFailedMessage().getPayload());
    throw exception; // make JMS broker redeliver
}

1 个答案:

答案 0 :(得分:0)

如果您希望进行rallback和重新传递,则您的错误流必须重新抛出异常,而不是像默认errorChannel那样吞下。您可以在这里找到类似的问题和答案。

<强>更新

好吧,不知道你的问题在哪里我有一个类似于你的测试用例:

    @Autowired
    private MessageChannel errorChannel;

    @Bean
    public IntegrationFlow jmsMessageDrivenFlow() {
        return IntegrationFlows
                .from(Jms.messageDrivenChannelAdapter(this.jmsConnectionFactory)
                        .configureListenerContainer(c -> c.sessionTransacted(true))
                        .errorChannel(this.errorChannel)
                        .destination("jmsMessageDriver"))
                .<String, String>transform(p -> {
                    throw new RuntimeException("intentional");
                })
                .get();
    }

    @Bean
    public IntegrationFlow errorHandlingFlow() {
        return IntegrationFlows.from(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
                .handle(m -> {
                    MessagingException exception = (MessagingException) m.getPayload();
                    Message<?> failedMessage = exception.getFailedMessage();
                    throw exception;
                })
                .get();
    }

在重新发送时,我在failedMessage

中看到了这些标题
"jms_redelivered" -> "true"
"JMSXDeliveryCount" -> "2"

是的,我们肯定在测试中使用嵌入式ActiveMQ。 顺便提一下,JMS ConnectionFactory是为Spring Boot ActiveMQAutoConfiguration提供的。