如何在Camel中处理故障转移负载均衡器失败?

5

我该如何捕获导致Camel故障转移负载均衡器失败的最终异常(例如,准备一个漂亮的(HTTP)响应而不是简单的堆栈跟踪)?

我有类似以下的代码:

from("jetty:http://0.0.0.0:8081/context")
  .process(frontendProcessor)
  .loadBalance()
    .failover(1,
              false,
              true,
              true,
              MyFancyException.class)
    .to("direct:foo", "direct:bar")
    .end()
  .process(responseProcessor)
  .stop();

使用:

from("direct:foo")
  .process(potentiallyThrowingMyFancyException);

(并且对于“direct:bar”也是一样)
没有负载均衡,我会使用 onException,但我似乎无法理解它如何与负载均衡及其 内部 异常处理相协调。一方面,我想记录堆栈跟踪,在负载均衡期间和另一方面,我想使用 onException 来创建一个漂亮的错误响应 - 最好在同一组件/实现中都有。所以我尝试了这个:
onException(Exception.class)
  .process(myErrorProcessor)
  .handled(true)
  .stop();

from("jetty:http://0.0.0.0:8081/context")
  .process(frontendProcessor)
  .loadBalance()
    .failover(1,
              false,
              true,
              true,
              MyFancyException.class)
    .to("direct:foo", "direct:bar")
    .end()
  .process(responseProcessor)
  .stop();

但是handled(true)似乎会破坏故障转移,另一方面,我认为当我使用onException来呈现最终的HTTP错误响应时,这是必要的。

onException错误处理器中,如何区分:

  1. 触发故障转移的异常,以及

  2. 故障转移负载均衡器完全失败,您可能希望为调用者创建一个漂亮的最终错误响应?

2个回答

3

我最终采用了Laurent在他的答案中提到的相同方法。我会发布解决方案,以便提供完整的示例,但接受他的答案。

请注意,在我的情况下,对他的答案进行了单一但重要的补充,即禁用默认错误处理程序。

我必须执行以下操作才能实现我想要的结果:

  1. 保留主路由与负载均衡器不变
  2. 路由中禁用默认错误处理程序
  3. 使用doTry+doCatch并重新抛出以进行调试日志记录

然后路由看起来像这样。

onException(Exception.class)
  .process(myErrorProcessor)
  .handled(true)
  .stop();

from("jetty:http://0.0.0.0:8081/context")
  .process(frontendProcessor)
  .loadBalance()
  .failover(1,
            false,
            true,
            true,
            MyFancyException.class)
  .to("direct:foo", "direct:bar")
.end()
.process(responseProcessor)
.stop();

并且:

errorHandler(noErrorHandler());

from("direct:foo")
  .doTry()
  .process(potentiallyThrowingMyFancyException)
  .doCatch(Exception.class)
  .process(logAndRethrowProcessor)
  .end();

(同样适用于“direct:bar”)

2
我更喜欢使用doTry...doCatch来处理异常 :-)
你可以将你的loadBalance EIP放在doTry...doCatch中,并根据需要处理最终的异常。 对于中间异常,也可以在from("direct:foo")from("direct:bar")路由中使用doTry...doCatch,并根据需要操作捕获的异常。当然,在处理完后别忘了重新抛出异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接