Home  >  Article  >  Operation and Maintenance  >  Operations and maintenance asked me to optimize the SpringBoot startup speed, and this is what I did!

Operations and maintenance asked me to optimize the SpringBoot startup speed, and this is what I did!

WBOY
WBOYforward
2023-06-08 18:52:311731browse

Spring Boot is undoubtedly the largest framework for Java back-end development. Based on Spring Boot, it has a complete tool chain and various starters. For daily business development, it can be said that the wheels are complete.

However, with the popularity of microservices and cloud native era, Spring Boot applications have exposed some problems, the most prominent of which are:

  • Slow startup
  • The application takes up too much memory
  • Cloud native applications have relatively high requirements for startup speed. When horizontal expansion is required, these new instances must be started within a short enough time to process new requests as quickly as possible.
  • #Cloud-native applications require as few resources as possible during runtime. Reducing the resources occupied by a single instance as much as possible means that more access requests can be supported at the same cost.
  • #Cloud native applications require smaller packaging volumes. Cloud native applications are packaged in the form of container images. The larger the size of the application image, the larger the storage space required, and the longer it takes to push and pull the image.

In fact, we all know that most of the startup time is due to Spring's need to load various beans, resulting in a decrease in startup speed

1. Delayed initialization of Bean

Generally, there are many time-consuming tasks in SpringBoot, such as establishing a database connection, creating an initial thread pool, etc. We can delay the initialization of these operations to optimize the startup speed. Purpose. The
spring.main.lazy-initialization property was introduced after Spring Boot version 2.2. If configured to true, all beans will be lazily initialized.

spring:main:lazy-initialization: true

After the delayed initialization is turned on locally, the startup can be 1~2 seconds faster.

environment

Configuration

(ten times average) startup speed

springboot2 jdk1.8


##≈10.3s


Lazy initialization Bean

≈8.63s

#

二、创建扫描索引

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

先看官方的解释:

Operations and maintenance asked me to optimize the SpringBoot startup speed, and this is what I did!

在项目中使用了@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);}}

Operations and maintenance asked me to optimize the SpringBoot startup speed, and this is what I did!

环境

配置

(十次平均值)启动速度

springboot2+jdk1.8


≈10.3s


+延迟初始化Bean

≈8.63s


+创建扫描索引

≈7.7s

Other tips:

1. Reduce the scope of @ComponentScan @SpringBootApplication when scanning classes

2. Turn off Spring Boot’s JMX monitoring , set spring.jmx.enabled=false

3. Set JVM parameters -noverify, do not verify classes

4. Delay loading of beans that are not loaded at startup 5. Use Spring Boot's global lazy loading 1

5. Try not to use annotations for AOPQ aspects, which will cause all methods to be scanned at startup 7. Turn off some endpoint monitoring functions

6. Exclude redundant projects Rely on jar

7. When scanning interfaces with swagger, specify to only scan classes under a certain path. 10. Scanning of Feign client interface reduces the scope of package scanning.

At this point, the startup speed should be considered optimized. It's quite extreme, but large memory usage is still a problem

3. Upgrade jdk17

Of course jdk has also made great efforts in this regard:

Memory The main reason for the high occupation is that the memory will not be returned to the operating system after it is occupied. This is gradually improving:

  • G1 JDK12 and later has been supported
  • ZGC JDK13 and later has supported

based on the characteristics of the Java language and Spring Boot Some implementation methods determine that even if the unused memory of G1/ZGC is turned on and returned to the operating system in time, the memory usage of Spring Boot is still much larger than that of compiled languages ​​​​such as Golang.

Therefore, if Java wants to solve the problems in the cloud native era, the current solutions are basically based on GraalVM, whether it is Quarkus or Micronaut.

So, does Spring Boot have a similar solution? :spring-graalvm-native

4. Upgrade SpringBoot3

spring-graalvm-native is a very important feature of springBoo6/SpringBoot3. It supports Using GraalVM to compile SpringBoot applications into local executable image files can significantly improve startup speed, peak performance, and reduce memory usage.

The above is the detailed content of Operations and maintenance asked me to optimize the SpringBoot startup speed, and this is what I did!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:51cto.com. If there is any infringement, please contact admin@php.cn delete