Spring Integration 的错误处理

如本手册开头的概述中所述,面向消息的框架(如 Spring Integration)背后的主要动机之一是促进组件之间的松散耦合。 消息渠道起着重要作用,因为生产者和消费者不必相互了解。 但是,优点也有一些缺点。 在松散耦合的环境中,有些事情会变得更加复杂,一个例子是错误处理。

将消息发送到通道时,最终处理该消息的组件可能与发送方在同一线程中运行,也可能不在运行。 如果使用简单的默认值(当元素没有子元素和“task-executor”属性时),消息处理发生在发送初始消息的同一线程中。 在这种情况下,如果抛出 an,它可以被发送方捕获,或者如果它是未捕获的,它可能会传播到发送方之外。 这与普通 Java 调用堆栈中的异常引发操作的行为相同。??DirectChannel????<channel>????<queue>????Exception????RuntimeException??

在调用方线程上运行的消息流可以通过消息传递网关(请参阅消息传递网关)或 (请参阅消息传递模板)调用。 在任一情况下,默认行为都是向调用方引发任何异常。 对于消息网关,请参阅错误处理,了解有关如何引发异常以及如何配置网关以将错误路由到错误通道的详细信息。 使用 或直接发送到 a 时,总是会向调用方引发异常。??MessagingTemplate????MessagingTemplate????MessageChannel??

添加异步处理时,事情变得更加复杂。 例如,如果“channel”元素确实提供了“queue”子元素(在Java和注释配置中),则处理消息的组件在与发送方不同的线程中运行。 使用 an 时也是如此。 发送者可能已将 放入频道并继续处理其他事情。 使用标准抛出技术无法将 直接抛出回该发送方。 相反,处理异步进程的错误要求错误处理机制也是异步的。??QueueChannel????ExecutorChannel????Message????Exception????Exception??

Spring 集成通过将错误发布到消息通道来支持其组件的错误处理。 具体来说,成为弹簧集成的有效载荷。 然后将其发送到消息通道,该消息通道以类似于“回复通道”解析的方式解析。 首先,如果在发生时处理的请求包含“errorChannel”标头(标头名称在常量中定义),则会将 发送到该通道。 否则,错误处理程序将发送到 Bean 名称为 (这也定义为常量:) 的“全局”通道。??Exception????ErrorMessage????Message????Message????Exception????MessageHeaders.ERROR_CHANNEL????ErrorMessage????errorChannel????IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME??

默认 Bean 由框架在内部创建。 但是,如果要控制设置,可以定义自己的设置。 以下示例演示如何在容量为 : 的队列支持的 XML 配置中定义错误通道:??errorChannel????500??

@BeanQueueChannel errorChannel() { return new QueueChannel(500);}

默认错误通道为 . 默认情况下,它有一个作为订阅者,日志记录级别和订阅顺序为 . 如果订阅其他使用终结点,这可能会引发异常,并且不希望抢占日志记录,请确保其他处理程序具有更高的顺序。??PublishSubscribeChannel????LoggingHandler????ERROR????Ordered.LOWEST_PRECEDENCE – 100??

这里要了解的最重要的事情是,基于消息传递的错误处理仅适用于在 . 这不适用于在与发送方相同的线程中运行的处理程序引发的异常(例如,通过本节前面所述的 )。??TaskExecutor????DirectChannel??

当计划轮询器任务的执行中发生异常时,这些异常将被包装在实例中并发送到“errorChannel”。 这是通过注入到全局 bean 中来完成的。 如果错误处理仍必须使用标准的“errorChannel”集成流逻辑完成,则建议将其用于任何自定义。 在这种情况下,可以使用注册的 bean。??ErrorMessage????MessagePublishingErrorHandler????taskScheduler????MessagePublishingErrorHandler????taskScheduler????integrationMessagePublishingErrorHandler??

若要启用全局错误处理,请在该通道上注册处理程序。 例如,您可以将 Spring 集成配置为订阅 . 然后,该路由器可以根据类型将错误消息传播到多个通道。??ErrorMessageExceptionTypeRouter????errorChannel????Exception??

从版本 4.3.10 开始,Spring 集成提供了 和 . 您可以将它们用作发布实例的常规机制。 可以在任何错误处理方案中调用或扩展它们。 将此类扩展为可与重试一起使用的实现,例如RequestHandlerRetryAdvice。 用于基于提供的异常和上下文构建 。 它可以注入任何或. 存储在上下文中。 可以将其用作它创建的属性。 正是这样做的。??ErrorMessagePublisher????ErrorMessageStrategy????ErrorMessage????ErrorMessageSendingRecoverer????RecoveryCallback????ErrorMessageStrategy????ErrorMessage????AttributeAccessor????MessageProducerSupport????MessagingGatewaySupport????requestMessage????ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY????AttributeAccessor????ErrorMessageStrategy????requestMessage????originalMessage????ErrorMessage????DefaultErrorMessageStrategy??

从版本 5.2 开始,框架组件引发的所有实例都包括组件资源和源,用于确定异常中的配置点。 在 XML 配置的情况下,资源是 XML 文件路径,并生成具有其属性的 XML 标记。 使用 Java 和注解配置,资源是一个类,源是一个方法。 在大多数情况下,目标集成流解决方案基于现成的组件及其配置选项。 当运行时发生异常时,堆栈跟踪中不涉及任何最终用户代码,因为执行是针对 bean,而不是它们的配置。 包含 Bean 定义的资源和源有助于确定可能的配置错误,并提供更好的开发人员体验。??MessageHandlingException????BeanDefinition????id????@Configuration????@Bean??

从版本 5.4.3 开始,默认错误通道配置了以下属性:当此通道上没有订阅者时(例如,当应用程序上下文停止时),不会以静默方式忽略消息。 在这种情况下,抛出 a,这可能会借给入站通道适配器的客户端回调,以否定(或回滚)源系统中的原始消息,以便重新传递或其他将来考虑。 要恢复以前的行为(忽略未调度的错误消息),必须将全局集成属性设置为 。 有关详细信息,请参阅全局属性和发布订阅通道配置(如果手动配置全局)。??requireSubscribers = true????MessageDispatchingException????spring.integration.channels.error.requireSubscribers????false????errorChannel??

另请参阅错误处理示例以获取更多信息。

想想我的影子,我会在你身后给你一个拥抱;

Spring Integration 的错误处理

相关文章:

你感兴趣的文章:

标签云: