如何一次重试骆驼直接路线?

时间:2019-12-10 17:26:52

标签: java error-handling apache-camel

使用骆驼,我想发送一个HTTP请求,如果失败,请采取一些纠正措施,然后再次尝试。

发送请求的过程被封装在direct路由中,并且需要生成唯一的令牌,除此之外,请求应该完全相同。如果请求第二次失败,则应该以“正常”方式失败。

我希望发送逻辑使用自己的路由,因为有时我想不重试就调用它。

如何使用骆驼DSL设置此方案?我尝试了onException和errorHandler的各种组合,但它似乎都没有捕捉到异常。

示例(无效):

from("direct:send-request-no-retry")
  .setHeader("token").exchange(this::generateToken)
  .to("http://example.com");

from("direct:fix-the-error")
  // ...
  ;

from("direct:send-request")
  .onException(HttpOperationFailedException.class)
    .to("direct:fix-the-error")
    .maximumRedeliveries(1)
    .useOriginalMessage()
    .end()
  .to("direct:send-request-no-retry");

1 个答案:

答案 0 :(得分:1)

我主要使用onException()子句作为全局异常处理程序。通过快速测试,将其直接放置到路由中并不能真正捕获异常。我想到的几个选择是:

第一个选项do-try子句:

        from("direct:send-request")
            .doTry()
                .to("direct:send-request-no-retry")
            .doCatch(HttpOperationFailedException.class)
                .to("direct:fix-the-error")
                .to("direct:send-request-no-retry")
            .doFinally()
                .whatevs()
            .endDoTry();

但这有点麻烦,因为您将不得不再次从doCatch子句中处理异常。另一个是从“发送请求不重试”中引发自定义异常。

 from("direct:send-request-no-retry")
            .setHeader("token").exchange(this::generateToken)
            .doTry()
                .to("http://example.com")
            .doCatch(HttpOperationFailedException.class)
                .throwException(new CustomExceptionThatExtendsRunTimeException())
            .doFinally();

onException(CustomExceptionThatExtendsRunTimeException.class)
        .handled(true)
        .to("direct:fix-the-error")
        .maximumRedeliveries(1)
        .useOriginalMessage()
        .to("direct:send-request-no-retry")
        .end();

我没有对此进行测试,所以我不确定这是否会创建一个无限的反馈循环,或者是否maximumRedeliveries将其切断。如果可以的话,您可以实现另一条“ direct:send-request-no-retry”路由,该路由不会引发customException而是只是默默失败或引发HttpOperationFailedException并从onException()那里传递请求。或将retryAmount设置为标头,然后在onException处理程序中检查该标头,以查看是否要重试。

customException用于以下目的:onException()子句从指定类型的每个路由捕获所有异常。而且我认为您不想将每个失败的http请求都传递给重试路由。