You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Camel 2.20.1迁移到3.20.1:多层RouteBuilder错误处理问题

Camel 2.20.1 → 3.20.1 迁移:错误处理路由问题解决方案

问题回顾

你有三个层级调用的RouteBuilder,期望RouteBuilderC抛出的异常能被RouteBuilderA的deadLetterChannel错误处理器处理,且仅重发RouteBuilderC的路由部分,而非整个A→B→C链路。旧版的includeRoutes方法已移除,尝试addRoutes无效。

路由结构参考

RouteBuilderA

@Override
public void configure() throws Exception {
    errorHandler(deadLetterChannel("direct:dead")
        .maximumRedeliveries(2)
        .redeliveryDelay(1000));

    from("direct:A")
        .to("direct:B");
}

RouteBuilderB

@Override
public void configure() throws Exception {
    from("direct:B")
        .to("direct:C");
}

RouteBuilderC

@Override
public void configure() throws Exception {
    errorHandler(noErrorHandler())

    from("direct:C")
       .throwException(new RuntimeException("Something went wrong"))
       .to("direct:end");
}

可行解决方案

方案1:通过全局onException定向重发(推荐)

在RouteBuilderA中定义全局异常捕获规则,指定仅重发RouteBuilderC的端点,同时保留死信通道的最终处理逻辑。异常会沿着调用链传递到RouteBuilderA的异常处理器,直接触发C的重发,无需经过B。

修改RouteBuilderA代码:

@Override
public void configure() throws Exception {
    // 捕获RuntimeException,仅重发RouteBuilderC的端点
    onException(RuntimeException.class)
        .maximumRedeliveries(2)
        .redeliveryDelay(1000)
        .retryAttemptedLogLevel(LoggingLevel.WARN)
        .to("direct:C");

    // 重发失败后,将消息转入死信队列
    errorHandler(deadLetterChannel("direct:dead")
        .useOriginalMessage() // 可选,保留原始消息内容
        .maximumRedeliveries(0)); // 关闭死信通道自身的重发,因为onException已处理重发逻辑

    from("direct:A")
        .to("direct:B");
}

RouteBuilderB和C保持原有代码不变:

  • RouteBuilderB无需添加任何错误处理器,异常会自然向上游传递
  • RouteBuilderC的noErrorHandler()确保异常直接抛出,不被自身路由拦截

方案2:通过doTry/doCatch在中间路由转发异常

如果需要更灵活的异常转发逻辑,可以在RouteBuilderB中捕获异常,直接将消息发送到RouteBuilderA的专用错误处理路由,由其负责重发C:

RouteBuilderB 修改:

@Override
public void configure() throws Exception {
    from("direct:B")
        .doTry()
            .to("direct:C")
        .doCatch(Exception.class)
            .to("direct:A-error-handler"); // 转发到A的错误处理端点
}

RouteBuilderA 添加错误处理路由:

@Override
public void configure() throws Exception {
    // 原有主路由
    from("direct:A")
        .to("direct:B");

    // 专用错误处理路由,负责重发C并处理死信
    from("direct:A-error-handler")
        .errorHandler(deadLetterChannel("direct:dead")
            .maximumRedeliveries(2)
            .redeliveryDelay(1000))
        .to("direct:C");
}

关键说明

  • 避免给RouteBuilderB添加noErrorHandler(),否则会触发整个A→B→C链路的重发,不符合需求
  • RouteBuilderC的noErrorHandler()是必要的,确保异常不被自身路由拦截,能向上传递
  • 方案1更简洁,利用Camel的全局异常处理机制,无需额外路由端点

内容的提问来源于stack exchange,提问作者Quoshak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:46:09