繁体   English   中英

AMQP Spring Integration错误处理

[英]AMQP Spring Integration error handling

我有一个类似于以下内容的集成流程:

@Bean
public IntegrationFlow auditFlow(@Qualifier("eventLoggingConnectionFactory") ConnectionFactory connectionFactory,
                                 @Qualifier("writeChannel") MessageChannel messageChannel,
                                 @Qualifier("parseErrorChannel") MessageChannel errorChannel) {
    return IntegrationFlows
            .from(Amqp.inboundAdapter(connectionFactory, auditQueue)
                    .errorChannel(errorChannel)
                    .concurrentConsumers(numConsumers)
                    .messageConverter(new MongoMessageConverter())) // converts JSON to org.bson.Document
            .enrichHeaders(e -> e.<Document>headerFunction(MongoWriteConfiguration.MONGO_COLLECTION_HEADER_KEY,
                    o -> getNamespace(o.getPayload())))
            .channel(messageChannel)
            .get();
}

如果引入格式错误的消息,消息转换器当然会出错,从而引发MessageConversionException。 在这种情况下,我当然不希望消息重新排队 - 但我也不想将默认值设置为NOT重新排队被拒绝的消息,因为我可以在AmqpInboundAdapterSpec上执行此操作。 对我来说,没有以这种方式重新排列错误的消息(以及为了调试目的而重新发布它们)的正确方法是什么?

更一般地说,同一流程中的下游流程可能会因语义错误的数据而出错 - 再一次,我不想重新排队。 我可以在那些时候抛出一个AmqpRejectAndDontRequeueException ,但后来我失去了关注的分离,这是这个问题的一半。 对这些异常采取行动的正确方法是什么 - 也许有一种方法可以转化为AmqpRejectAndDontRequeueException

入站适配器的SimpleMessageListenerContainerConditionalRejectingErrorHandler )中的默认错误处理程序就是这样(它检测到MessageConversionException并抛出AmqpRejectAndDontRequeueException )。

您可以通过注入自己的FatalExceptionStrategy来查找其他异常类型并以相同的方式处理它们来自定义ConditionalRejectingErrorHandler

DefaultExceptionStrategy看起来像这样......

@Override
public boolean isFatal(Throwable t) {
    if (t instanceof ListenerExecutionFailedException
            && t.getCause() instanceof MessageConversionException) {
        if (logger.isWarnEnabled()) {
            logger.warn("Fatal message conversion error; message rejected; "
                    + "it will be dropped or routed to a dead letter exchange, if so configured: "
                    + ((ListenerExecutionFailedException) t).getFailedMessage(), t);
        }
        return true;
    }
    return false;
}

只有在原因链中还没有AmqpRejectAndDontRequeueException才会调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM