最小化 Spring 引导启动时间
Minimise Spring Boot Startup Time
在我看来,SpringBoot 项目需要很长时间才能加载。这可能是因为 SpringBoot 正在为您配置组件,其中一些您甚至可能不需要。
最明显的做法是从 class 路径中删除不必要的依赖项。然而,这还不够。
有什么办法可以查出SpringBoot配置了哪些模块让你挑出不需要的并禁用掉?
一般情况下,还有什么可以加快 SpringBoot 应用程序的启动时间吗?
我可以告诉你我 运行 一个大型(800,000 多行代码)应用程序,通过 Spring MVC、JMS、Atomikos 事务、Hibernate、JMX 使用 restful 网络服务支持和嵌入 Tomcat。有了这一切,该应用程序将在大约 19 秒内在我的本地桌面上启动。
Spring Boot 尽量不配置您不使用的模块。但是,很容易引入您不希望的其他依赖项和配置。
请记住,Spring 引导遵循配置范例的约定,只需将一个库放在 class 路径中即可导致 Spring 引导尝试配置模块以使用图书馆。此外,通过使用 @RestController 注释 class 之类的简单操作,将触发 Spring 启动以自动配置整个 Spring MVC 堆栈。
您可以看到幕后发生的事情并启用调试日志记录,就像在从命令行启动应用程序时指定 --debug
一样简单。您还可以在 application.properties.
中指定 debug=true
此外,您可以在 application.properties
中设置日志级别,如下所示:
logging.level.org.springframework.web: DEBUG
logging.level.org.hibernate: ERROR
如果您检测到不需要的自动配置模块,可以将其禁用。可以在此处找到相关文档:http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration
示例如下:
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
一些可能有用的额外提示。
- 使用 OpenJ9 而不是 Hotspot 进行开发
- 如果您使用 Hibernate,请设置
hibernate.ddl-auto=none
而不是 update
- 将 vmargs 设置为
-Xquickstart
- 如果您使用 OpenJ9 - 将 vmargs 设置为
-XX:TieredStopAtLevel=1 -noverify
- 如果您使用 Hotspot - 使用 IDE build 而不是 Gradle build
- 使用Undertow instead of Tomcat
- 不要滥用注释处理工具(mapstruct, immutables...),这会减慢构建过程
另外:
因为 this article 建议对本地开发环境使用 @ComponentScan(lazyInit = true)
。
TL;DR
What we want to achieve is to enable the bean lazy loading only in your local development environment and leave eager initialization for production. They say you can’t have your cake and eat it too, but with Spring you actually can. All thanks to profiles.
@SpringBootApplication
public class LazyApplication {
public static void main(String[] args) {
SpringApplication.run(LazyApplication.class, args);
}
@Configuration
@Profile("local")
@ComponentScan(lazyInit = true)
static class LocalConfig {
}
}
在我看来,SpringBoot 项目需要很长时间才能加载。这可能是因为 SpringBoot 正在为您配置组件,其中一些您甚至可能不需要。 最明显的做法是从 class 路径中删除不必要的依赖项。然而,这还不够。
有什么办法可以查出SpringBoot配置了哪些模块让你挑出不需要的并禁用掉?
一般情况下,还有什么可以加快 SpringBoot 应用程序的启动时间吗?
我可以告诉你我 运行 一个大型(800,000 多行代码)应用程序,通过 Spring MVC、JMS、Atomikos 事务、Hibernate、JMX 使用 restful 网络服务支持和嵌入 Tomcat。有了这一切,该应用程序将在大约 19 秒内在我的本地桌面上启动。
Spring Boot 尽量不配置您不使用的模块。但是,很容易引入您不希望的其他依赖项和配置。
请记住,Spring 引导遵循配置范例的约定,只需将一个库放在 class 路径中即可导致 Spring 引导尝试配置模块以使用图书馆。此外,通过使用 @RestController 注释 class 之类的简单操作,将触发 Spring 启动以自动配置整个 Spring MVC 堆栈。
您可以看到幕后发生的事情并启用调试日志记录,就像在从命令行启动应用程序时指定 --debug
一样简单。您还可以在 application.properties.
此外,您可以在 application.properties
中设置日志级别,如下所示:
logging.level.org.springframework.web: DEBUG
logging.level.org.hibernate: ERROR
如果您检测到不需要的自动配置模块,可以将其禁用。可以在此处找到相关文档:http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration
示例如下:
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
一些可能有用的额外提示。
- 使用 OpenJ9 而不是 Hotspot 进行开发
- 如果您使用 Hibernate,请设置
hibernate.ddl-auto=none
而不是update
- 将 vmargs 设置为
-Xquickstart
- 如果您使用 OpenJ9 - 将 vmargs 设置为
-XX:TieredStopAtLevel=1 -noverify
- 如果您使用 Hotspot - 使用 IDE build 而不是 Gradle build
- 使用Undertow instead of Tomcat
- 不要滥用注释处理工具(mapstruct, immutables...),这会减慢构建过程
另外:
因为 this article 建议对本地开发环境使用 @ComponentScan(lazyInit = true)
。
TL;DR
What we want to achieve is to enable the bean lazy loading only in your local development environment and leave eager initialization for production. They say you can’t have your cake and eat it too, but with Spring you actually can. All thanks to profiles.
@SpringBootApplication public class LazyApplication { public static void main(String[] args) { SpringApplication.run(LazyApplication.class, args); } @Configuration @Profile("local") @ComponentScan(lazyInit = true) static class LocalConfig { } }