Apache Flink+Spring Boot Actuator失效及集群启动异常问题求助
问题描述
基于Apache Flink 1.15 + Spring Boot 2.7.x开发流处理应用,使用maven shade插件打包胖Jar,pom配置参考btleedev示例。已引入以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>${spring.version}</version> </dependency>
核心代码:
主类:
@SpringbootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Flink配置类:
@Configuration public class FlinkConfig { @Bean public StreamExecutionEnvironment executionEnvironment() { return StreamExecutionEnvironment.getExecutionEnvironment(); } }
任务类:
@Component public class MyJob { @Autowired private StreamExecutionEnvironment environment; public void buildJob() { DataStream stream = environment.fromSource(...); // job streaming logic ... // execute job environment.execute(); } }
遇到两个问题:
- IDE启动时,Flink任务和Tomcat(8080端口)正常运行,但Actuator无端点暴露日志,
http://localhost:8080/actuator/health无法访问。 - 提交Jar到Flink独立集群,执行命令
standalone-job.sh start --job-classname my.flink.job.Application,仅添加actuator依赖时触发报错:
*************************** APPLICATION FAILED TO START *************************** Description: Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.
pom的build配置片段:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${target.java.version}</source> <target>${target.java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> </dependency> </dependencies> <executions> <!-- Run shade goal on package phase --> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <excludes> <exclude>org.apache.flink:flink-shaded-force-shading</exclude> <exclude>com.google.code.findbugs:jsr305</exclude> <exclude>ch.qos.logback:*</exclude> <exclude>org.slf4j:*</exclude> <exclude>org.apache.logging.log4j:*</exclude> </excludes> </artifactSet> <filters> <filter> <!-- Do not copy the signatures in the META-INF folder. Otherwise, this might cause SecurityExceptions when using the JAR. --> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.tooling</resource> </transformer> <transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer"> <resource>META-INF/spring.factories</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>my.flink.job.Application</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> </configuration> </execution> </executions> </plugin> ... </plugins> </build>
问题分析与解决方案
一、IDE中Actuator无法访问的原因及解决
原因
- 端点未配置暴露:Spring Boot 2.x默认仅暴露
health和info端点,但health默认隐藏详细信息,且未配置management.endpoints.web.exposure.include时,端点无法被外部访问。 - Flink任务阻塞Spring初始化:
environment.execute()是阻塞方法,若MyJob的buildJob在Spring上下文初始化阶段被调用,会导致Tomcat容器和Actuator端点的注册流程被阻塞,无法完成初始化。
解决步骤
- 配置Actuator端点暴露
在application.properties中添加:# 按需暴露端点,示例为暴露所有 management.endpoints.web.exposure.include=* # 允许health端点显示详细状态 management.endpoint.health.show-details=always - 延迟Flink任务启动
修改MyJob类,通过ApplicationRunner实现延迟执行,确保Spring上下文(包括Actuator)初始化完成后再启动Flink任务:@Component public class MyJob implements ApplicationRunner { @Autowired private StreamExecutionEnvironment environment; @Override public void run(ApplicationArguments args) throws Exception { buildJob(); } public void buildJob() { DataStream stream = environment.fromSource(...); // job streaming logic ... environment.execute(); } }
二、Flink集群启动报错的原因及解决
原因
- 依赖与环境不匹配:Flink集群环境不需要Spring Boot的Web容器(Tomcat),但当前依赖包含
spring-boot-starter-web,导致Spring Boot尝试启动Web服务;Actuator依赖会触发Web自动配置,但集群环境缺少Servlet容器相关Bean的加载条件。 - 类加载冲突:Flink的类加载机制与Spring Boot的自动配置逻辑冲突,导致
ServletWebServerFactoryBean无法被正确初始化。
解决步骤
- 拆分开发与集群依赖
将spring-boot-starter-web限定为仅本地开发环境生效,集群环境不引入:
或通过Maven Profile精准控制:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring.version}</version> <!-- 仅本地开发时提供,集群环境不打包 --> <scope>provided</scope> </dependency><profiles> <profile> <id>dev</id> <activation><activeByDefault>true</activeByDefault></activation> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </profile> <profile> <id>cluster</id> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>${spring.version}</version> <exclusions> <!-- 排除Web相关依赖 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </profile> </profiles> - 禁用Web自动配置
在主类上排除Web容器的自动配置类,避免Spring Boot尝试启动Web服务:@SpringBootApplication(exclude = {ServletWebServerFactoryAutoConfiguration.class, WebMvcAutoConfiguration.class}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } - 检查Shade插件排除项
确认shade插件的artifactSet未误排除Servlet容器相关依赖(如Tomcat),确保Actuator核心依赖被正确打包进胖Jar。
三、额外优化建议
- 本地开发利用Spring Boot Web容器调试Actuator,集群运行时仅保留Flink任务与必要的Spring上下文,避免冗余Web服务。
- 结合Flink自带的集群监控界面(默认8081端口),减少对Spring Boot Actuator的依赖。
- 确保Shade插件的Spring配置文件合并逻辑正常,避免自动配置类丢失。
内容的提问来源于stack exchange,提问作者Vin
相关产品推荐
相关产品推荐

