错误处理程序
Camel 支持可插拔的 ErrorHandler 策略,以处理事件驱动消费者处理过程中出现的错误。
另一种方法是在 DSL 中使用异常条款直接指定错误处理。
使用 try ... catch ... finally
与错误处理相关的是 Try Catch Finally DSL,您可以直接在路由中使用它。它基本上是对 Java 语言中普通 try catch finally 的模仿,但功能更强大。
目前,Camel 开箱即用的实现方式有
非转让
-
DefaultErrorHandler 是 Camel 的默认错误处理程序。该错误处理程序不支持死信队列,它会将异常传播回调用者,就像根本没有错误处理程序一样。它的功能有限。 -
死信通道支持在将信息发送到死信端点之前尝试多次重新发送信息交换 -
NoErrorHandler 表示不进行错误处理
转让
-
TransactionErrorHandler 是 Camel 中用于事务路由的默认错误处理程序。请参阅事务客户端 EIP 模式。
这些错误处理程序可在 DSL 中应用于整个规则集或特定路由规则,我们将在接下来的示例中进行演示。单个 RouteBuilder 中的每个路由规则都继承了错误处理规则
所提供错误处理程序的简短摘要
死信通道
死信通道最多会以 1 秒钟的延迟重新发送 6 次,如果交换失败,将以 ERROR 级别记录。
您可以配置使用默认死锁终端: 或 XML DSL:
<camel:errorHandler id="deadLetterErrorHandler" type="DeadLetterChannel" deadLetterUri="log:dead">
<camel:camelContext errorHandlerRef="deadLetterErrorHandler">
...
</camel:camelContext>
各种错误处理程序支持的功能
以下是错误处理器支持的功能明细:
特点 | 由以下错误处理程序支持 |
---|---|
所有范围 |
|
关于异常 |
|
当 |
|
继续 |
|
处理 |
|
自定义异常政策 |
|
使用正文 |
|
retryWhile |
|
交货时 |
|
重新交付政策 |
|
asyncDelayedRedelivery |
|
在停止时重新交付 |
|
死信队列 | 死信通道 |
onPrepareFailure |
|
有关上述功能的其他文档,请参阅例外条款文档。
标准
错误处理程序的作用域为
-
CamelContext(骆驼上下文):在 XML 中全局使用,或在 Java DSL 中仅在同一RouteBuilder
中全局使用。 -
路线 - 每条路线单独设置
下面的示例展示了如何为 RouteBuilder
注册全局错误处理程序:
RouteBuilder builder = new RouteBuilder() {
public void configure() {
errorHandler(deadLetterChannel("seda:error"));
// here is our regular route
from("seda:a").to("seda:b");
}
};
下面的示例展示了如何注册路由特定的错误处理程序
RouteBuilder builder = new RouteBuilder() {
public void configure() {
// this route is using a nested error handler
from("seda:a")
// here we configure the error handler
.errorHandler(deadLetterChannel("seda:error"))
// and we continue with the routing here
.to("seda:b");
// this route will use the default error handler
from("seda:b").to("seda:c");
}
};
基于弹簧的配置
Java DSL 与 Spring DSL 在 Java DSL 和 Spring DSL 中,错误处理程序的配置略有不同。Spring DSL 更依赖于标准 Spring Bean 配置,而 Java DSL 则使用流畅构建器。
可将错误处理程序配置为 Spring Bean,并在其中进行作用域设置:
-
全局(
<camelContext>
标签) -
每个路由(<route>
标签) -
或按政策(<policy>
/<transacted>
标签)
错误处理程序使用 errorHandlerRef
属性进行配置。
错误处理程序层次结构 错误处理程序是继承的,因此如果你只设置了一个全局错误处理程序,那么它就会在所有地方使用。但你可以在路由中覆盖它,并使用另一个错误处理程序。 |
基于弹簧的配置示例
在本示例中,我们在路由上配置了一个死信通道,该通道最多可重传 3 次,重试前会有少许延迟。首先,我们使用 route
标记上的 errorHandlerRef
属性配置 myDeadLetterErrorHandler 的引用。
<camelContext xmlns="http://camel.apache.org/schema/spring">
<template id="myTemplate"/>
<!-- set the errorHandlerRef to our DeadLetterChannel, this applies for this route only -->
<route errorHandlerRef="myDeadLetterErrorHandler">
<from uri="direct:in"/>
<process ref="myFailureProcessor"/>
<to uri="mock:result"/>
</route>
</camelContext>
然后我们配置 myDeadLetterErrorHandler,它就是我们的死信通道。该配置是使用 bean 元素的标准 Spring 配置。最后,我们为重新交付策略配置了另一个 Spring Bean,在这里我们可以配置重新交付的次数、延迟等选项。
<!-- here we configure our DeadLetterChannel -->
<bean id="myDeadLetterErrorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder">
<!-- exchanges is routed to mock:dead in cased redelivery failed -->
<property name="deadLetterUri" value="mock:dead"/>
<!-- reference the redelivery policy to use -->
<property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
</bean>
<!-- here we set the redelivery settings -->
<bean id="myRedeliveryPolicyConfig" class="org.apache.camel.processor.errorhandler.RedeliveryPolicy">
<!-- try redelivery at most 3 times, after that the exchange is dead and its routed to the mock:dead endpoint -->
<property name="maximumRedeliveries" value="3"/>
<!-- delay 250ms before redelivery -->
<property name="redeliveryDelay" value="250"/>
</bean>