当味精处理引发异常时,如何有效地支持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]
答案 0 :(得分:0)
它可以与消息驱动的通道适配器一起使用,但由于this question,我想这不是您想要的。
由于轮询的适配器使用JmsTemplate.receive()
操作,因此在调用流时该消息已被确认。
您需要使用带有JmsTransactionManager
的事务轮询器,以使错误流引发的异常回滚事务并重新传递消息。