Apache Camel框架之Error handling

Apache Camel提供了许多处理路由过程出现的Exception的机制,本文简单介绍一下其异常处理的方法.

1,默认的情况是在路由过程中没有处理的异常会被被抛出到路由的发起者,对发生异常的路由停止进行后续步骤的处理.

比如下面的路由在process(p1)出错,那么当前路由停止,文件不会到达"d:/temp/outbox",同时d:/temp/inbox里造成异常的那个文件仍然留在d:/temp/inbox文件夹中,由于Camel会轮询这个文件夹,所以下次轮询时,对这个文件处理的时候会继续异常.

from("file:d:/temp/inbox?delay=30000").process(p0).process(p1).to("file:d:/temp/outbox");
public class TProcessor0 implements Processor{
    public void process(Exchange exchange) throws Exception {        
        System.out.println("what if here has a transaction,later processing failed?");
    }
}
public class TProcessor0 implements Processor{
    public void process(Exchange exchange) throws Exception {        
        String nullStr=null;
        nullStr.length();
    }
}

如果路由改成如下:因为异常是在process(p1)里发生,所以文件会会到达"d:/temp/outbox",但是d:/temp/inbox造成异常的文件仍然在d:/temp/inbox文件夹中,下次轮询时对这个文件处理的时候会继续异常.

from("file:d:/temp/inbox?delay=30000").to("file:d:/temp/outbox").process(p0).process(p1);

默认情况基本上就是已经做过的步骤没有rollback的操作,如果需要事务控制就更不行了.[会另外写一篇关于Camel如何做事务控制TransactionErrorHandler]

2,利用Camel提供的DeadLetterChannel将出错的消息路由到"死队列"里,然后停止当前的路由,其示例图如下:(图片来源于Camel in Action)

errorHandler(deadLetterChannel("file:d:/temp/error"));
 from("file:d:/temp/inbox?delay=30000").process(p0).process(p1).to("file:d:/temp/outbox");
在process(p1)出错,处理会停止处理process(p1)之后的步骤,d:/temp/inbox里造成异常的文件会被放到d:/temp/error文件夹,d:/temp/inbox里的文件会被移走.

errorHandler(deadLetterChannel("file:d:/temp/error"));写在某一个routebuilder里的时候,是这个routebuilder所有路由的error handler.如果要为其中某一个路由指定error handler,示例如下:from("file:d:/temp/inbox?delay=30000").errorHandler(deadLetterChannel("file:d:/temp/error")).process(p0).process(p1).to("file:d:/temp/outbox");               
3,利用Camel提供的onException功能,当有异常发生的时候,会根据不同的异常类型,跳到和onException里指定异常匹配的的步骤进行处理.

onException(NullPointerException.class).process(p2).handled(true).to("file:d:/temp/nullerror").end();
onException(TestException.class).process(p2).continued(true).to("file:d:/temp/TEerror").end();

from("file:d:/temp/inbox?delay=30000").process(p0).process(p1).to("file:d:/temp/outbox");//route xx

如上面在route builder里定义的话,当有NullPointerException发生的时候,会转到第一个onException,这时候会停止进行route xx的后续步骤处理(handled(true)设置的作用),将错误消息保存到:d:/temp/nullerror.当有TestException发生的时候,会转到第二个onException,这时候会将错误消息保存到:d:/temp/TEerror,忽略异常继续routexx的后续步骤(continued(true设置的作用).

Camel还支持类似如java try catch的语法,如下:TestException由process(p2)处理.

from("file:d:/temp/inbox?delay=30000").doTry().process(p0).process(p1).to("file:d:/temp/outbox")
.doCatch(TestException.class).process(p2)
.doCatch(NullPointerException.class).process(p2).end();

Camel的onException还可以和onWhen,onRedeliver,retryWhile结合使用.

onException(XXXException.class)
.onWhen(bean(XXX.class, "isIllegalData"))
.handled(true)
.to("file:/acme/files/illegal");

XXXException为异常的类型的类,XXX.class有一个isIllegalData方法返回true或者false,对异常进行更细致的区别处理.

errorHandler(defaultErrorHandler()
.maximumRedeliveries(3)
.onRedeliver(new MyOnRedeliveryProcessor());

onException(IOException.class)
.maximumRedeliveries(5)
.onRedeliver(new MyOtherOnRedeliveryProcessor());

在重新处理之前对exchange里的内容做一些改动的时候用onRedeliver.

public class MyRetryRuleset {
public boolean shouldRetry(@Header(Exchange.REDELIVERY_COUNTER) Integer counter,Exception causedBy) {
...
}

onException(IOException.class).retryWhile(bean(MyRetryRuletset.class));

在异常发生后捕捉到异常的点循环重试,直到MyRetryRuletset的shouldRetry方法返回false为止.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值