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

如何让Spring Boot集成Camel应用在from端点不可用时正常启动?

问题背景

基于Spring Boot的Apache Camel应用需要提升容错能力:当MQ、SMPP等from端点不可用时,应用仍能正常启动,且定期重试连接,待端点恢复后自动接收消息。当前代码在SMPP端点不可用时会直接启动失败。

当前代码

// Application.java
@SpringBootApplication
@ConfigurationPropertiesScan
public class Application 
{   
    @Autowired private CamelContext context;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
   @Bean
    CommandLineRunner init(ProducerTemplate template) 
    {
        return args -> 
        {
            context.addRoutes(new MQRouteBuilder());
            context.addRoutes(new SMPPRouteBuilder());
        };
    }
}

// SMPPRouteBuilder.java
public class SMPPRouteBuilder extends RouteBuilder
{
    public void configure() throws Exception
    {
        from("smpp://{{camel.component.smpp.configuration.host}}").to("direct:processSMS");
        //...
    }
}

启动报错

java.lang.IllegalStateException: Failed to execute CommandLineRunner at
org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787)
~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
...
Caused by: java.net.UnknownHostException: localhostInvalid
...

解决方案

通过配置Camel允许启动失败+自定义路由重试策略实现需求:

1. 配置Camel允许路由启动失败

添加CamelContextConfiguration,让Camel在部分路由启动失败时不终止整个应用:

@Bean
CamelContextConfiguration camelContextConfiguration() {
    return context -> {
        // 允许单个路由启动失败,不影响应用启动
        context.setAllowStartupFailures(true);
    };
}

2. 自定义路由重试策略

创建AutoRetryRoutePolicy,在路由启动失败后定期重试启动:

@Component
public class AutoRetryRoutePolicy implements RoutePolicy {

    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    // 重试间隔,单位毫秒,可配置到application.properties
    private static final long RETRY_DELAY = 30000;

    @Override
    public void onStartupFailure(Route route, Throwable cause) {
        // 路由启动失败,安排下一次重试
        scheduler.schedule(() -> attemptRestart(route), RETRY_DELAY, TimeUnit.MILLISECONDS);
    }

    private void attemptRestart(Route route) {
        try {
            CamelContext context = route.getRouteContext().getCamelContext();
            RouteStatus status = context.getRouteStatus(route.getId());
            // 仅当路由未启动时尝试重启
            if (!status.isStarted()) {
                context.startRoute(route.getId());
            }
        } catch (Exception e) {
            // 重试失败,继续安排下一次重试
            scheduler.schedule(() -> attemptRestart(route), RETRY_DELAY, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public void onRemove(Route route) {
        // 路由移除时关闭调度器
        scheduler.shutdown();
    }

    // 实现其他空方法
    @Override public void onInit(Route route) {}
    @Override public void onStart(Route route) {}
    @Override public void onStop(Route route) {}
    @Override public void onSuspend(Route route) {}
    @Override public void onResume(Route route) {}
}

3. 给目标路由绑定重试策略

修改SMPPRouteBuilder,将重试策略绑定到SMPP路由上:

public class SMPPRouteBuilder extends RouteBuilder {

    @Autowired
    private AutoRetryRoutePolicy autoRetryRoutePolicy;

    @Override
    public void configure() throws Exception {
        from("smpp://{{camel.component.smpp.configuration.host}}")
                .routeId("smppRoute")
                .routePolicy(autoRetryRoutePolicy) // 绑定重试策略
                .to("direct:processSMS");
    }
}

效果说明

  • 应用启动时,即使SMPP端点不可用,也能正常启动,MQ路由会正常监听消息
  • SMPP路由启动失败后,会每隔30秒自动重试连接,直到端点恢复可用,自动开始接收消息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:27:05