Spring Boot 项目启动过慢排查方案

🔍 第一步:定位启动瓶颈

排查启动慢的问题,核心是找到时间花在哪里了。以下几种方式由易到难:

开启启动耗时日志

application.properties 中添加:

properties
spring.main.startup=buffered

或者引入 Actuator 的 startup 端点,访问 /actuator/startup,可以看到每个 Bean 的初始化耗时,快速定位慢 Bean。

查看自动配置报告

在配置文件中设置日志级别:

properties
logging.level.org.springframework.boot.autoconfigure=debug

启动后日志中会出现 ==== Conditions evaluation report ====,列出所有自动配置类的匹配/排除情况,帮你发现加载了哪些不需要的配置。

使用开源分析工具

推荐 Spring Startup Analyzer,它会自动采集启动过程数据,生成交互式 HTML 分析报告,直观展示每个阶段的耗时。


🎯 第二步:常见慢点及优化方案

根据定位结果,以下是启动慢的常见原因和对应解决办法:

过多的自动配置

项目依赖多时,Spring Boot 会尝试为各类依赖做自动配置。排除不需要的:

java
@SpringBootApplication(exclude = {    ElasticsearchAutoConfiguration.class,    RabbitAutoConfiguration.class})

或者在配置文件中排除:

properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchAutoConfiguration

大量 Bean 初始化耗时

  • 开启懒加载:让 Bean 在第一次使用时才创建,而不是启动时一次性全部初始化:

    properties
    spring.main.lazy-initialization=true
  • 单个 Bean 懒加载:对个别耗时 Bean 加 @Lazy 注解,比如有 @Async 线程池初始化时加载外部资源的 Bean。

数据源/连接池初始化慢

数据库连接池(如 Redis、MySQL)启动时预创建大量连接是常见瓶颈。例如 Redis 配置了最大连接数 100,启动时就创建 100 个连接,可以改为惰性初始化:

properties
spring.data.redis.lettuce.pool.min-idle=0

组件扫描范围过大

默认 @ComponentScan 会扫描启动类所在包及所有子包,加载太多不必要的 Bean。可以缩小扫描范围:

java
@SpringBootApplication(scanBasePackages = {"com.example.app"})

依赖过多

仔细审查 pom.xml,去除不必要的依赖。依赖越多,类加载和资源扫描的时间越长。


⚡ 第三步:进阶优化手段

如果以上基础优化后仍不理想,可以考虑:

  • 优化 JVM 参数:增大初始堆内存(-Xms)和最大堆内存(-Xmx),选择合适的垃圾回收器(如 G1GC),减少启动时的内存压力。

  • 切换 Servlet 容器:将默认的 Tomcat 替换为 Undertow,在内存占用和启动速度上通常表现更优。

  • 添加 spring-context-indexer:编译时生成静态索引文件,启动时直接使用,跳过类路径扫描:

    xml
    <dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-context-indexer</artifactId>    <optional>true</optional></dependency>
  • Bean 异步初始化:使用 spring-async-bean-starter 等工具,将无依赖关系的 Bean 并行初始化,实测可降低 50%-60% 的启动时间。


📌 总结排查流程

  1. 先量化:用 Actuator startup 端点或 Spring Startup Analyzer 拿到每个 Bean 的耗时数据
  2. 找 Top N 慢 Bean:重点关注数据源连接池、外部服务调用、@PostConstruct 方法
  3. 对症下药:懒加载、排除无用配置、缩小扫描范围、优化连接池参数
  4. 进阶手段:JVM 调优、异步初始化、切换容器

按照这个流程走一遍,90 秒的启动时间通常可以压缩到 20-30 秒以内。