如果在路由中定义了死信通道错误处理程序,Camel 故障转移负载均衡器不会故障转移到下一个目标

Camel Failover Load Balancer not failing over to next target if a Dead Letter Channel Error Handler is defined in the route

我已经使用故障转移负载均衡器定义了一条骆驼路线,如下所示:

from(activemq:foo)
    .errorHandler(deadLetterChannel(activemq:foo.dlq).onPrepareFailure(failureProcessor))
    .process(processor)
    .loadBalance()
        .failover(2, true, true)
            .to(activemq:queue1, activemq:queue2)
    .end();

使用上面定义的路由,如果传递到 queue1 失败,异常由错误处理程序处理,消息直接放入 foo.dlq,负载均衡器不会故障转移到下一个目标。

如何定义路线:
它应该故障转移到所有路由,如果对所有路由的传递都失败(完全失败),它应该将控制发送到错误处理程序,错误处理程序应该将消息发送到 DLQ。

我认为您应该在负载均衡器中关闭 inheritErrorHandler(第二个参数),即:

.loadBalance()
   .failover(2, false, true)

这样,两个节点之一上的任何故障都会传播到 loadBalancer 处理器,而不是 DLQ。

但是如果整个负载均衡过程失败(即:如果两个节点都失败),DLQ将被启动。

提示:如果缩进代码,传播逻辑会更清晰一些:

from("...")
  .errorHandler(...)
  .loadBalance().failover(2, false, true) // level 1
    .to("...") // level 2
    .to("...") // level 2
  .end();

您有两个身份级别;每个级别都有自己的错误处理:

  • 2 级错误由负载平衡器管理
  • 1 级错误由 DLQ 管理

我很惊讶。 我只有 运行 以下测试(在 Camel 3.9 中)- 有 2 个虚拟 http 端点:

from("timer://demo?period=60s")
    .errorHandler( deadLetterChannel("log:DLQ") )
    .log("Run")
    .loadBalance().failover(2, false, false)
        .to("direct:node1")
        .to("direct:node2")
    .end()
    .log("success");

from("direct:node1")
    .errorHandler( noErrorHandler() )
    .log("Attempt on node#1")
    .to("http://localhost:8881/ws");

from("direct:node2")
    .errorHandler( noErrorHandler() )
    .log("Attempt on node#2")
    .to("http://localhost:8882/ws");

这是输出:

INFO  | route1                         | Camel (Test) thread #0 - t | Run
INFO  | route2                         | Camel (Test) thread #0 - t | Attempt on node#1
INFO  | route3                         | Camel (Test) thread #0 - t | Attempt on node#2
INFO  | DLQ                            | Camel (Test) thread #0 - t | Exchange[ExchangePattern: InOnly, BodyType: null, Body: [Body is null]]

你清楚地看到每个节点上都有一次尝试,最后交换到了DLQ

如果我启用 inheritErrorHandler,现在的输出是:

INFO  | route1                         | Camel (Test) thread #0 - t | Run
INFO  | route2                         | Camel (Test) thread #0 - t | Attempt on node#1
INFO  | DLQ                            | Camel (Test) thread #0 - t | Exchange[ExchangePattern: InOnly, BodyType: null, Body: [Body is null]]