使用JMS重试/重新交付的Spring Integration Java DSL

时间:2018-08-13 16:07:40

标签: spring-integration spring-integration-dsl

当味精处理引发异常时,如何有效地支持JMS重新交付?

我有一个使用JMS(ActiveMQ)和connectionFactory的流,该连接工厂配置为允许n次重新交付尝试。

我希望在处理msg时发生任何错误,导致msg在connectionFactory配置允许的情况下被送回进行重新交付的次数尽可能多,然后在尝试最大重新交付后,将其交付给DLQ。经常使用AMQ。

一个相关的SO问题的答案表明,我可能有一个errorChannel会重新引发,该异常会触发重新交付:Spring Integration DSL ErrorHandling

但是,以下情况并没有发生:

/***
 * Dispatch msgs from JMS queue to a handler using a rate-limit
 * @param connectionFactory
 * @return
 */
@Bean
public IntegrationFlow flow2(@Qualifier("spring-int-connection-factory") ConnectionFactory connectionFactory) {

    IntegrationFlow flow =  IntegrationFlows.from(
            Jms.inboundAdapter(connectionFactory)
                    .configureJmsTemplate(t -> t.receiveTimeout(1000))
                    .destination(INPUT_DIRECT_QUEUE),
            e -> e.poller(Pollers
                    .fixedDelay(5000)
                    .errorChannel("customErrorChannel")
                    //.errorHandler(this.msgHandler)
                    .maxMessagesPerPoll(2))
    ).handle(this.msgHandler).get();

    return flow;
}

@Bean
public MessageChannel customErrorChannel() {
    return MessageChannels.direct("customErrorChannel").get();
}

@Bean
public IntegrationFlow customErrorFlow() {
    return IntegrationFlows.from(customErrorChannel())
            .handle ("simpleMessageHandler","handleError")
            .get();
}

errorChannel方法隐含:

   public void handleError(Throwable t) throws Throwable {
        log.warn("got error from customErrorChannel");
        throw t;
    }

在flow2中从处理程序引发异常时,errorChannel会获取该异常,但是重新抛出会导致MessageHandlingException:

2018-08-13 09:00:34.221  WARN 98425 --- [ask-scheduler-5] c.v.m.i.jms.SimpleMessageHandler         : got error from customErrorChannel
2018-08-13 09:00:34.224  WARN 98425 --- [ask-scheduler-5] o.s.i.c.MessagePublishingErrorHandler    : Error message was not delivered.

org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.messaging.MessageHandlingException: error occurred in message handler [simpleMessageHandler]; nested exception is java.lang.IllegalArgumentException: dont want first try, failedMessage=GenericMessage [payload=Enter some text here for the message body..., headers={jms_redelivered=false, jms_destination=queue://_dev.directQueue, jms_correlationId=, jms_type=, id=c2dbffc8-8ab0-486f-f2e5-e8d613d62b6a, priority=0, jms_timestamp=1534176031021, jms_messageId=ID:che2-39670-1533047293479-4:9:1:1:8, timestamp=1534176034205}]
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:107) ~[spring-integration-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.handler.BeanNameMessageProcessor.processMessage(BeanNameMessageProcessor.java:61) ~[spring-integration-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:93) ~[spring-integration-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]

1 个答案:

答案 0 :(得分:0)

它可以与消息驱动的通道适配器一起使用,但由于this question,我想这不是您想要的。

由于轮询的适配器使用JmsTemplate.receive()操作,因此在调用流时该消息已被确认。

您需要使用带有JmsTransactionManager的事务轮询器,以使错误流引发的异常回滚事务并重新传递消息。