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

时间:2018-04-09 11:58:53

标签: java apache-camel

如何捕获导致Camel故障转移负载均衡器失败的 final 异常(例如,准备好的(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,但我似乎无法理解它如何与负载均衡器及其内部良好协作异常处理。一方面,我想记录堆栈跟踪 DURING 负载平衡,另一方面我想使用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 个答案:

答案 0 :(得分:3)

我最终使用了与Laurent在答案中提到的相同的方法。我将发布解决方案以获得完整的示例,但接受他的回答。

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

我必须做以下事情才能实现我想要的目标:

  1. 保留带有负载均衡器的主路径
  2. 停用路线
  3. 中的默认错误处理程序
  4. 使用doTry + doCatch进行重新抛出以进行调试记录
  5. 然后路线看起来像这样。

    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”相同)

答案 1 :(得分:2)

我自己更像一个doTry...doCatch家伙: - )

您可以将loadBalance EIP包含在doTry ... doCatch中,并根据需要处理最终异常。 对于中间异常也是如此:在 from(“direct:foo”) from(“direct:bar”)路由中使用doTry ... doCatch并对其进行操作你喜欢抓住异常。当然,不要忘记事后重新抛出它们。