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

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();
    }
}

遇到两个问题:

  1. IDE启动时,Flink任务和Tomcat(8080端口)正常运行,但Actuator无端点暴露日志,http://localhost:8080/actuator/health无法访问。
  2. 提交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无法访问的原因及解决

原因

  1. 端点未配置暴露:Spring Boot 2.x默认仅暴露health和info端点,但health默认隐藏详细信息,且未配置management.endpoints.web.exposure.include时,端点无法被外部访问。
  2. Flink任务阻塞Spring初始化:environment.execute()是阻塞方法,若MyJob的buildJob在Spring上下文初始化阶段被调用,会导致Tomcat容器和Actuator端点的注册流程被阻塞,无法完成初始化。

解决步骤

  1. 配置Actuator端点暴露
    在application.properties中添加:
    # 按需暴露端点,示例为暴露所有
    management.endpoints.web.exposure.include=*
    # 允许health端点显示详细状态
    management.endpoint.health.show-details=always
    
  2. 延迟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集群启动报错的原因及解决

原因

  1. 依赖与环境不匹配:Flink集群环境不需要Spring Boot的Web容器(Tomcat),但当前依赖包含spring-boot-starter-web,导致Spring Boot尝试启动Web服务;Actuator依赖会触发Web自动配置,但集群环境缺少Servlet容器相关Bean的加载条件。
  2. 类加载冲突:Flink的类加载机制与Spring Boot的自动配置逻辑冲突,导致ServletWebServerFactory Bean无法被正确初始化。

解决步骤

  1. 拆分开发与集群依赖
    将spring-boot-starter-web限定为仅本地开发环境生效,集群环境不引入:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring.version}</version>
        <!-- 仅本地开发时提供,集群环境不打包 -->
        <scope>provided</scope>
    </dependency>
    
    或通过Maven Profile精准控制:
    <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>
    
  2. 禁用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);
        }
    }
    
  3. 检查Shade插件排除项
    确认shade插件的artifactSet未误排除Servlet容器相关依赖(如Tomcat),确保Actuator核心依赖被正确打包进胖Jar。

三、额外优化建议

  • 本地开发利用Spring Boot Web容器调试Actuator,集群运行时仅保留Flink任务与必要的Spring上下文,避免冗余Web服务。
  • 结合Flink自带的集群监控界面(默认8081端口),减少对Spring Boot Actuator的依赖。
  • 确保Shade插件的Spring配置文件合并逻辑正常,避免自动配置类丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 04:24:45