SpringBoot 启动慢怎么优化
一 、看启动耗时分布
接了Springboot Actuator的/actuator/startup端点,这是Spingboot 2.4+自带的能力,不用额外装APM,访问一下各阶段耗时。一看数据:
Bean的初始化52秒,数据源加载18秒,自定义ApplicationRunner 6秒,其他2秒。
52秒的Bean初始化占了三分之二,先从这里下手优化。
SpringBoot启动的时候,会扫描所有的@Component/@Service/@Configuration标注的类,实例化每一个Bean,执行他的依赖注入和初始化方法。
项目越大,Bean越多,这个过程就很慢。52秒意味着什么,说明这个项目大概有上千个Bean,,每一个都要在启动时完成实例化--哪怕有些bean这个服务压根用不到。
第一步,排除不需要的包。在启动类上加@ComponentScan的excludeFilters,把和本服务无关的jar包排除掉。比如这个项目的订单服务,但pom里引用了用户服务的SDK,
里面带了一堆@Configuration--这些Bean订单服务根本用不到,但启动时照样初始化。排除后,Bean的数量从1200降到800,启动时间从78秒降到55秒。
第二步,懒加载。spring.main.lazy-initialization=true,这个配置的思路是:所有bean不在启动时创建,而是第一次用到的时候才实例化。
打个比方,就像餐厅开张--原来是一开门就先把100道菜先做好,不管有没有人点;懒加载就是等开门了,客人点什么你再做什么。效果很明显,800个Bean里真正启动时用到的不到200个,剩余的600个全部推迟了,启动时间就从55秒降到28秒。
但是懒加载有个坑,如果Bean之间循环依赖,开了懒加载不会在启动时报错,但会在运行时某个接口第一次被调用时爆出--这比启动报错危险多,因为问题被延迟到了线上。
为什么?正常启动Spring通过三级缓存发现循环依赖并处理,但懒加载模式下Bean不创建,Spring在启动阶段根本没机会检测到这些依赖关系。所以正确做法:开懒加载之前,先关掉懒加载的正常启动一次,看启动日志里有没有循环依赖告警,有的话先解除掉,再开懒加载。
二、数据源连接18秒
28秒了,还差一截。看数据源--HikariCP默认启动时就会创建连接池,minimum-idle默认值就是10,意味着启动立刻建10个数据库连接。如果数据库响应慢(比如跨机房、网络抖动),这一个动作就能1拖十几秒。
改法:spring.datasource.hikari.minimum-idle=0.这个0的意思就是启动时不创建任何连接,第一个请求来了再按需创建。HikariCP的连接创建速度极快,一个连接大概几十毫秒,用户根本感知不到。
三、ApplicationRunner 里同步10
还剩6秒。翻代码发现有个ApplicationRunner在启动时加载一份本地配置文件,读文件+解析+校验,6秒全花在这里。这个配置不是接口启动必须的--改成@Async异步执行,主线程不等他完成,直接走完启动流程。
改完,18秒变成12秒。

浙公网安备 33010602011771号