Spring Boot无Web环境下Apache Camel应用启动后立即关闭问题排查
问题分析与解决
问题背景
基于Spring Boot 2.7.3 + Apache Camel 3.18.1开发的无Web应用,功能为轮询本地目录并将文件上传至SFTP服务器,以Kubernetes CronJob形式部署。已配置camel.springboot.main-run-controller=true,但应用启动后立即停止。
关键代码与配置
Maven依赖
<dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-file-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-ftp-starter</artifactId> </dependency>
Camel路由实现
@Component public class FtpFileUploaderRouteBuilder extends RouteBuilder { private static final String ROUTE_ID = "ftp-file-uploader"; @Override public void configure() throws Exception { from("file://data?initialDelay=100&repeatCount=1") .toD("sftp://ftp:21?username=username&password=password"); } }
Spring Boot主类
@SpringBootApplication public class Application { public static void main(String[] args) { final SpringApplication app = new SpringApplication(Application.class); app.setWebApplicationType(WebApplicationType.NONE); app.setBannerMode(Banner.Mode.OFF); System.exit(SpringApplication.exit(app.run(args))); } }
核心日志片段
2022-09-01 14:25:09.432 INFO [ftp-uploader-service,,] 41548 --- [ main] c.c.g.o.f.ServiceApplication : Started ServiceApplication in 6.649 seconds (JVM running for 9.108) 2022-09-01 14:25:09.439 INFO [ftp-uploader-service,,] 41548 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.18.1 (camel-1) is shutting down (timeout:45s)
问题原因
主类中的System.exit(SpringApplication.exit(app.run(args)))是直接诱因:SpringApplication.exit()会主动触发Spring上下文关闭流程,即使配置了camel.springboot.main-run-controller=true,也会被这行代码强制终止应用。
解决方案
修改主类代码,移除System.exit和SpringApplication.exit的调用,让Camel的MainRunController维持应用运行:
@SpringBootApplication public class Application { public static void main(String[] args) { final SpringApplication app = new SpringApplication(Application.class); app.setWebApplicationType(WebApplicationType.NONE); app.setBannerMode(Banner.Mode.OFF); app.run(args); } }
额外优化建议
- 路由中的
repeatCount=1表示仅轮询一次,若需适配CronJob的定时执行场景,可移除该参数,或根据调度周期调整轮询策略。 - SFTP默认端口为22,当前路由中
ftp:21是FTP协议端口,需修正为ftp:22(或匹配服务器实际配置)。 - 敏感信息(SFTP用户名、密码)建议通过配置文件注入,避免硬编码:
路由中使用占位符引用:sftp.host=your-ftp-host sftp.port=22 sftp.username=your-username sftp.password=your-passwordfrom("file://data?initialDelay=100") .toD("sftp://${sftp.host}:${sftp.port}?username=${sftp.username}&password=${sftp.password}");
内容的提问来源于stack exchange,提问作者landal79
相关产品推荐
相关产品推荐

