Spring Boot 启动慢,我排查了一圈

举报
yd_241780069 发表于 2026/10/24 10:07:59 2026/10/24
【摘要】 起因项目启动从 20 秒慢慢涨到快 90 秒,本地改一行代码重启一次,等得人想砸键盘。一开始以为是自己电脑不行,后来发现测试环境也一样,才开始认真查。这篇记一下排查过程和最后动的东西。 先量,别猜第一步不是改代码,是搞清楚时间花在哪。Spring Boot 启动日志里默认有耗时,但不够细。我是加了个 ApplicationStartup 的监听,或者简单点,直接在 main 里打时间戳:p...

起因

项目启动从 20 秒慢慢涨到快 90 秒,本地改一行代码重启一次,等得人想砸键盘。一开始以为是自己电脑不行,后来发现测试环境也一样,才开始认真查。

这篇记一下排查过程和最后动的东西。

先量,别猜

第一步不是改代码,是搞清楚时间花在哪。

Spring Boot 启动日志里默认有耗时,但不够细。我是加了个 ApplicationStartup 的监听,或者简单点,直接在 main 里打时间戳:

public static void main(String[] args) {
    long start = System.currentTimeMillis();
    SpringApplication.run(DemoApplication.class, args);
    System.out.println("启动耗时: " + (System.currentTimeMillis() - start) + "ms");
}

这只能看总时长。要看每个 Bean 的初始化时间,我开了 -Ddebug 不够,最后用的是 BufferingApplicationStartup:

SpringApplication app = new SpringApplication(DemoApplication.class);
app.setApplicationStartup(new BufferingApplicationStartup(2048));
app.run(args);

然后配合 /actuator/startup 端点,能看到每个启动步骤的耗时,哪些 Bean 慢一眼就出来了。

查出来的几个大头

第一个,扫描范围太大。 启动类在 com.example 根包下,@SpringBootApplication 默认扫整个子树,连测试用的、废弃的类都扫进来了。而且项目里还引了一堆 starter,每个都带自己的自动配置,条件注解挨个评估一遍也要时间。

第二个,某个 starter 拖了后腿。 排查时发现有个数据源相关的自动配置,明明没配数据库,它还在初始化连接池、跑健康检查。这种就是典型的“引了用不上”。后来在 application.yml 里排掉:

spring:
  autoconfigure:
    exclude:
      - com.example.some.AutoConfiguration

Spring Boot 3 里这个属性改叫 spring.autoconfigure.exclude 了,写法一样。

第三个,@PostConstruct 里干重活。 有个 Service 在 @PostConstruct 里加载本地缓存文件,文件不小,每次启动都读一遍。改成懒加载,第一次访问的时候再初始化,启动时间直接少了十来秒。

第四个,JPA / Hibernate 的 ddl-auto。 开发环境开着 update,启动时 Hibernate 要连库比对表结构,库越大越慢。这个生产环境本来就不该开,开发环境也改成了 none,需要建表就用迁移脚本。

顺手做的几件事

  • 关掉不必要的日志级别。logging.level.root=INFO 就行,DEBUG 开着的时候光是日志输出就能拖慢几秒。
  • 懒初始化。spring.main.lazy-initialization=true 能明显提速,但要注意:Bean 报错会推迟到第一次使用时才暴露,本地开发可以开,线上慎用。
  • 排除无用依赖。mvn dependency:tree 看一眼,好几个引进来根本没用过的包,删掉之后启动和打包都快了点。

关于懒初始化,多说两句

lazy-initialization 我一开始全开了,启动确实快,但踩了个坑:某个 Bean 依赖的配置项写错了,以前启动就报错,开了懒加载之后要等接口调过去才炸。本地调试还行,测试环境就不合适了。

后来改成只对特定 Bean 加 @Lazy,比如那些初始化重、但启动时用不到的。全局开关还是关着。

小结

启动慢基本就这几个来源:扫描范围、自动配置、初始化逻辑、数据库连接、日志。排查顺序我是先量总时长,再看步骤耗时,定位到具体 Bean 再动。

改完之后从 90 秒降到 30 秒左右,本地热重启快了不少。剩下的 30 秒里有一大半是数据库连接和框架本身的开销,再压就得动架构了,暂时没那个必要。

先记到这,后面再有新发现接着补。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。