0

0

运维让我优化SpringBoot启动速度,我是这么干的!

WBOY

WBOY

发布时间:2023-06-08 18:52:31

|

2052人浏览过

|

来源于51CTO.COM

转载

spring boot毫无疑问是 java 后端开发的第一大框架,基于spring boot有着一套完整的工具链,各种各样的starter。对于日常业务开发而言,可以说是轮子很全。

但随着微服务和云原生时代的流行,Spring Boot应用却暴露出了一些问题,其中比较突出的有:

  • 启动慢
  • 应用内存占用多
  • 云原生应用对启动速度的要求比较高。当需要进行水平扩展时,要求这些新的实例必须在足够短的时间内完成启动,从而尽快的处理新增的请求。
  • 云原生应用要求在运行时占用尽可能少的资源。尽可能的减少单个实例占用的资源,就意味着可以用同样的成本,支持更多的访问请求。
  • 云原生应用要求更小的打包体积。云原生应用以容器镜像的形式打包。应用镜像的尺寸越大,所需要的存储空间也会越大,推送和拉取镜像所耗费的时间也会更长。

其实我们都比较清楚大部分的启动时间是由于 Spring 需要加载各种 Bean 导致启动速度下降的

一、延迟初始化Bean

一般在 SpringBoot 中都拥有很多的耗时任务,比如数据库建立连接、初始线程池的创建等等,我们可以延迟这些操作的初始化,来达到优化启动速度的目的。Spring Boot 2.2 版本后引入
spring.main.lazy-initialization属性,配置为 true 会将所有 Bean 延迟初始化。

spring:main:lazy-initialization: true

个人本地开启延迟初始化之后,启动能快了1~2秒。

环境

Mokker AI
Mokker AI

AI产品图添加背景

下载

配置

(十次平均值)启动速度

springboot2+jdk1.8


≈10.3s


延迟初始化Bean

≈8.63s

二、创建扫描索引

Spring5 之后提供了spring-context-indexer功能,可以通过在编译时创建一个静态候选列表来提高大型应用程序的启动性能。

先看官方的解释:

运维让我优化SpringBoot启动速度,我是这么干的!

在项目中使用了@Indexed之后,编译打包的时候会在项目中自动生成META-INT/spring.components文件。

当Spring应用上下文执行ComponentScan扫描时,META-INT/spring.components将会被CandidateComponentsIndexLoader 读取并加载,转换为CandidateComponentsIndex对象,这样的话@ComponentScan不在扫描指定的package,而是读取CandidateComponentsIndex对象,从而达到提升性能的目的.

我们只需要将依赖引入,然后在启动类上使用@Indexed注解即可。这样在程序编译打包之后会生成
META-INT/spring.components文件,当执行@ComponentScan扫描类时,会读取索引文件,提高扫描速度。

<dependency>	<groupId>org.springframework</groupId>	<artifactId>spring-context-indexer</artifactId>	<optional>true</optional></dependency>
@Indexed@SpringBootApplicationpublic class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

运维让我优化SpringBoot启动速度,我是这么干的!

环境

配置

(十次平均值)启动速度

springboot2+jdk1.8


≈10.3s


+延迟初始化Bean

≈8.63s


+创建扫描索引

≈7.7s

其他技巧:

1、减少@ComponentScan @SpringBootApplication扫描类时候的范围

2、关闭 Spring Boot 的 JMX监控,设置spring.jmx.enabled=false

3、设置JVM参数 -noverify ,不对类进行验证

4、对非必要启动时加载的Bean,延迟加载5、使用Spring Boot的全局懒加载一

5、AOPQ切面尽量不使用注解方式,这会导致启动时扫描全部方法7、关闭endpoint的一些监控功能

6、排除项目多余的依赖jar

7、swagger扫描接口时,指定只扫描某个路径下的类10、Feign 客户端接口的扫描缩小包扫描范围

到这启动速度应该算是优化的比较极致了, 但是内存占用大依然是问题

三、 升级jdk17

当然jdk也在这方面做了很大的努力:

内存占用多主要是内存占用后不会归还操作系统,这个正在逐步改善:

  • G1 JDK12及之后 已支持
  • ZGC JDK13及之后 已支持

于Java语言的特性及Spring Boot的一些实现方式,决定了即便是开启了G1/ZGC的未使用内存及时归还操作系统,Spring Boot的内存占用,仍然远大于Golang这种编译型语言。

所以,Java想要解决云原生时代的问题,目前的方案基本都是基于GraalVM来的,不管是Quarkus(夸克)还是Micronaut都是。

那么,Spring Boot有没有类似的方案呢?:spring-graalvm-native

四、升级SpringBoot3

spring-graalvm-native是springBoo6/SpringBoot3 非常重大的一个特性,支持使用 GraalVM 将 SpringBoot 的应用程序编译成本地可执行的镜像文件,可以显著提升启动速度、峰值性能以及减少内存使用。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

243

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

352

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

407

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

428

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

200

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1254

2025.06.17

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

48

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 6.4万人学习

Git 教程
Git 教程

共21课时 | 4万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号