此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1! |
正如本手册开头的概述中所描述的,面向消息的框架(如Spring Integration)背后的主要动机之一是促进组件之间的松散耦合。 消息渠道起着重要作用,因为生产者和消费者不必相互了解。 但是,优点也有一些缺点。 在松散耦合的环境中,有些事情会变得更加复杂,一个例子是错误处理。
将消息发送到通道时,最终处理该消息的组件可能与发送方在同一线程中运行,也可能不在线程中运行。
如果使用简单的默认值(当元素没有子元素且没有“task-executor”属性时),则消息处理发生在发送初始消息的同一线程中。
在这种情况下,如果抛出 an,它可以被发送者捕获,或者如果它是未捕获的,它可能会传播到发送方。
这与普通 Java 调用堆栈中的异常抛出操作的行为相同。DirectChannel
<channel>
<queue>
Exception
RuntimeException
在调用方线程上运行的消息流可以通过邮件网关(请参阅邮件网关)或(请参阅 MessagingTemplate
)调用。
无论哪种情况,默认行为都是向调用方抛出任何异常。
对于邮件网关,请参阅错误处理,详细了解如何引发异常以及如何配置网关以将错误路由到错误通道。
使用 a 或直接发送到 a 时,总是会向调用方抛出异常。MessagingTemplate
MessagingTemplate
MessageChannel
添加异步处理时,事情变得更加复杂。
例如,如果“channel”元素确实提供了一个“queue”子元素(在Java&注解配置中),则处理消息的组件在与发送方不同的线程中运行。
使用 an 时也是如此。
发件人可能已将其放入频道并继续执行其他操作。
使用标准投掷技术无法将 T 直接扔回该发送者。
相反,处理异步进程的错误要求错误处理机制也是异步的。QueueChannel
ExecutorChannel
Message
Exception
Exception
Spring Integration 通过将错误发布到消息通道来支持其组件的错误处理。
具体来说,成为 Spring Integration 的有效负载。
然后将其发送到消息通道,该通道以类似于“replyChannel”解析的方式进行解析。
首先,如果在发生请求时正在处理的请求包含“errorChannel”标头(标头名称在常量中定义),则将发送到该通道。
否则,错误处理程序将发送到 Bean 名称为 (这也定义为常量: )的“全局”通道。Exception
ErrorMessage
Message
Message
Exception
MessageHeaders.ERROR_CHANNEL
ErrorMessage
errorChannel
IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME
默认 Bean 由框架在内部创建。
但是,如果要控制设置,可以定义自己的设置。
下面的示例演示如何在 XML 配置中定义错误通道,该配置由容量为 :errorChannel
500
-
Java
-
XML
@Bean
QueueChannel errorChannel() {
return new QueueChannel(500);
}
<int:channel id="errorChannel">
<int:queue capacity="500"/>
</int:channel>
默认错误通道是 .
默认情况下,它有一个 as 订阅者,其日志记录级别和 subscription 顺序为 。
如果订阅了其他使用终结点,则可能会引发异常,并且您不希望抢占日志记录,请确保其他处理程序具有更高的顺序。PublishSubscribeChannel LoggingHandler ERROR Ordered.LOWEST_PRECEDENCE - 100 |
默认错误通道是 .
默认情况下,它有一个 as 订阅者,其日志记录级别和 subscription 顺序为 。
如果订阅了其他使用终结点,则可能会引发异常,并且您不希望抢占日志记录,请确保其他处理程序具有更高的顺序。PublishSubscribeChannel LoggingHandler ERROR Ordered.LOWEST_PRECEDENCE - 100 |
这里要了解的最重要的事情是,基于消息传递的错误处理仅适用于在 .
这不适用于在与发送方相同的线程中操作的处理程序引发的异常(例如,通过本节前面所述的 处理程序)。TaskExecutor
DirectChannel
当计划的轮询器任务执行中发生异常时,这些异常将包装在实例中并发送到“errorChannel”。
这是通过注入全局 bean 来完成的。
如果错误处理仍必须使用标准的“errorChannel”集成流逻辑完成,则建议将其用于任何自定义。
在这种情况下,可以使用已注册的 bean。ErrorMessage MessagePublishingErrorHandler taskScheduler MessagePublishingErrorHandler taskScheduler integrationMessagePublishingErrorHandler |
当计划的轮询器任务执行中发生异常时,这些异常将包装在实例中并发送到“errorChannel”。
这是通过注入全局 bean 来完成的。
如果错误处理仍必须使用标准的“errorChannel”集成流逻辑完成,则建议将其用于任何自定义。
在这种情况下,可以使用已注册的 bean。ErrorMessage MessagePublishingErrorHandler taskScheduler MessagePublishingErrorHandler taskScheduler integrationMessagePublishingErrorHandler |
若要启用全局错误处理,请在该通道上注册处理程序。
例如,您可以将 Spring Integration 配置为订阅 .
然后,该路由器可以根据类型将错误消息传播到多个通道。ErrorMessageExceptionTypeRouter
errorChannel
Exception
从版本 4.3.10 开始,Spring Integration 提供了 和 .
您可以将它们用作发布实例的常规机制。
可以在任何错误处理方案中调用或扩展它们。
将此类扩展为可与重试一起使用的实现,例如 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 & Annotation 配置中,资源是一个类,源是一个方法。
在大多数情况下,目标集成流解决方案基于现成的组件及其配置选项。
当在运行时发生异常时,堆栈跟踪中不涉及任何最终用户代码,因为执行是针对 Bean 的,而不是针对其配置的。
包括 Bean 定义的资源和源有助于确定可能的配置错误,并提供更好的开发人员体验。MessageHandlingException
BeanDefinition
id
@Configuration
@Bean
从版本 5.4.3 开始,默认错误通道配置为当此通道上没有订阅者时(例如,当应用程序上下文停止时),不会以静默方式忽略消息。
在这种情况下,会抛出一个,它可能会借用入站通道适配器的客户端回调,以否定地确认(或回滚)源系统中的原始消息,以便重新传递或将来考虑其他事项。
若要还原以前的行为(忽略未调度的错误消息),必须将全局集成属性设置为 。
有关详细信息,请参阅全局属性和 PublishSubscribeChannel
配置(如果手动配置全局)。requireSubscribers = true
MessageDispatchingException
spring.integration.channels.error.requireSubscribers
false
errorChannel
有关详细信息,另请参阅错误处理示例。