如果在路由中定义了死信通道错误处理程序,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]]
我已经使用故障转移负载均衡器定义了一条骆驼路线,如下所示:
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]]