programing

Spring Boot 시작 시간 단축

nasanasas 2020. 9. 10. 07:57
반응형

Spring Boot 시작 시간 단축


Spring Boot 애플리케이션이 있습니다. 나는 많은 의존성을 추가했고 (불행히도 그것들이 모두 필요해 보인다) 시작 시간이 상당히 증가했다. 하는 것만으로도 SpringApplication.run(source, args)10 초가 걸립니다.

그것이 "사용 된"것에 비하면 그다지 많지 않을 수도 있지만, 대부분 개발 흐름을 깨뜨리기 때문에 그렇게 많이 걸리는 것이 불행합니다. 이 시점에서 애플리케이션 자체는 다소 작기 때문에 대부분의 시간이 앱 클래스 자체가 아니라 추가 된 종속성과 관련이 있다고 가정합니다.

문제가 클래스 경로 스캔이라고 가정하지만 다음 방법을 잘 모르겠습니다.

  • 문제인지 확인 (예 : Spring Boot를 "디버그"하는 방법)
  • 그것이 정말로 원인이라면 어떻게 제한 할 수 있습니까? 예를 들어 일부 종속성 또는 패키지에 Spring이 스캔해야하는 내용이 포함되어 있지 않다는 것을 알고 있다면이를 제한하는 방법이 있습니까?

나는 시작하는 동안 병렬 빈 초기화를 갖도록 Spring을 강화 하면 속도가 빨라질 것이라고 가정 하지만 그 향상 요청은 2011 년부터 진행되지 않고 열려 있습니다. Investigate Tomcat JarScanning 속도 향상 과 같은 Spring Boot 자체의 다른 노력이 있지만 Tomcat에 국한되어 포기되었습니다.

이 기사 :

통합 테스트를 겨냥했지만을 사용 lazy-init=true하는 것이 좋지만 Java 구성을 사용하여 Spring Boot의 모든 Bean에 이것을 적용하는 방법을 모르겠습니다-여기에 포인터가 있습니까?

(기타) 제안을 환영합니다.


Spring Boot는 필요하지 않을 수있는 많은 자동 구성을 수행합니다. 따라서 앱에 필요한 자동 구성 만 좁힐 수 있습니다. 포함 된 자동 구성의 전체 목록을 보려면 org.springframework.boot.autoconfigureDEBUG 모드 ( logging.level.org.springframework.boot.autoconfigure=DEBUGin application.properties) 에서 로깅을 실행하십시오 . 또 다른 옵션은 옵션을 사용하여 스프링 부트 애플리케이션을 실행하는 --debug것입니다.java -jar myproject-0.0.1-SNAPSHOT.jar --debug

출력에는 다음과 같은 내용이 있습니다.

=========================
AUTO-CONFIGURATION REPORT
=========================

이 목록을 검사하고 필요한 자동 구성 만 포함하십시오.

@Configuration
@Import({
        DispatcherServletAutoConfiguration.class,
        EmbeddedServletContainerAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        JacksonAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        PropertyPlaceholderAutoConfiguration.class,
        ThymeleafAutoConfiguration.class,
        WebMvcAutoConfiguration.class,
        WebSocketAutoConfiguration.class,
})
public class SampleWebUiApplication {

이 블로그 게시물 에서 코드를 복사 했습니다 .


지금까지 가장 많이 득표 한 답변은 틀린 것은 아니지만 내가보고 싶은 깊이에 이르지 않으며 과학적 증거를 제공하지 않습니다. Spring Boot 팀은 Boot 2.0의 시작 시간을 줄이기위한 연습을 진행했으며 티켓 11226 에는 많은 유용한 정보가 포함되어 있습니다. 조건 평가에 타이밍 정보를 추가 할 수 있는 티켓 7939있지만 특정 ETA가없는 것 같습니다.

부팅 시작 디버깅을위한 가장 유용하고 체계적인 접근 방식은 Dave Syer에 의해 수행되었습니다. https://github.com/dsyer/spring-boot-startup-bench

저도 비슷한 사용 사례를 가지고 있었기 때문에 JMH로 마이크로 벤치마킹에 대한 Dave의 접근 방식을 취해 실행했습니다. 결과는 boot-benchmark 프로젝트입니다. 나는 의해 생성 된 실행 항아리 사용하여 임의의 봄 부팅 응용 프로그램의 시작 시간을 측정 할 수는 있도록 설계 bootJar(이전이라고 bootRepackage부팅 1.5) Gradle을 작업. 자유롭게 사용하고 피드백을 제공하십시오.

내 결과는 다음과 같습니다.

  1. CPU가 중요합니다. 많이.
  2. -Xverify : none으로 JVM을 시작 하면 큰 도움이됩니다.
  3. 불필요한 자동 구성을 제외하면 도움이됩니다.
  4. Dave는 JVM 인수 -XX : TieredStopAtLevel = 1을 권장 했지만 내 테스트는 그에 대해 크게 개선되지 않았습니다. 또한 -XX:TieredStopAtLevel=1첫 번째 요청이 느려질 것입니다.
  5. 가 있었다 보고서 호스트 이름 확인이 느린되는,하지만 난 그것이 내가 테스트 응용 프로그램에 대한 문제 찾지 못했습니다.

이 질문 / 답변에서 설명했듯이 가장 좋은 방법은 필요하다고 생각하는 것만 추가하는 대신 필요하지 않다는 것을 알고있는 종속성을 제외하는 것입니다.

참조 : Spring Boot 시작 시간 최소화

요약해서 말하자면:

명령 줄에서 애플리케이션을 시작할 때 --debug를 지정하는 것처럼 간단하게 진행중인 작업을 확인하고 디버그 로깅을 활성화 할 수 있습니다. application.properties에서 debug = true를 지정할 수도 있습니다.

또한 application.properties의 로깅 수준을 다음과 같이 간단하게 설정할 수 있습니다.

logging.level.org.springframework.web : DEBUG logging.level.org.hibernate : ERROR

If you detect an auto-configured module you don't want, it can be disabled. The docs for this can be found here: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration

An example would look like:

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

Spring Boot 2.2.M1 has added feature to support Lazy Initialization in Spring Boot.

By default, when an application context is being refreshed, every bean in the context is created and its dependencies are injected. By contrast, when a bean definition is configured to be initialized lazily it will not be created and its dependencies will not be injected until it’s needed.

Enabling Lazy Initialization Set spring.main.lazy-initialization to true

For more details please check Doc


If you're trying to optimize development turn-around for manual testing, I strongly recommend the use of devtools.

Applications that use spring-boot-devtools will automatically restart whenever files on the classpath change.

Just recompile -- and the server will restart itself (for Groovy you only need to update the source file). if you're using an IDE (e.g. 'vscode'), it may automatically compile your java files, so just saving a java file can initiate a server restart, indirectly -- and Java becomes just as seamless as Groovy in this regard.

The beauty of this approach is that the incremental restart short-circuits some of the from-scratch startup steps -- so your service will be back up and running much more quickly!


Unfortunately, this doesn't help with startup times for deployment or automated unit testing.


WARNING: If you don't use Hibernate DDL for automatic DB schema generation and you don't use L2 cache, this answer is NOT applicable to you. Scroll ahead.

My finding is that Hibernate adds significant time to application startup. Disabling L2 cache and database initialization results in faster Spring Boot app startup. Leave cache ON for production and disable it for your development environment.

application.yml:

spring:
  jpa:
    generate-ddl: false
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        cache:
          use_second_level_cache: false
          use_query_cache: false

Test results:

  1. L2 cache is ON and ddl-auto: update

    INFO 5024 --- [restartedMain] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 23331 ms
    INFO 5024 --- [restartedMain] b.n.spring.Application : Started Application in 54.251 seconds (JVM running for 63.766)
    
  2. L2 cache is OFF and ddl-auto: none

    INFO 10288 --- [restartedMain] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 9863 ms
    INFO 10288 --- [restartedMain] b.n.spring.Application : Started Application in 32.058 seconds (JVM running for 37.625)
    

Now I wonder what will I do with all this free time


I find it strange nobody suggested these optimizations before. Here're some general tips on optimizing project build and startup when developing:

  • exclude development directories from antivirus scanner:
    • project directory
    • build output directory (if it's outside of project directory)
    • IDE indices directory (e.g. ~/.IntelliJIdea2018.3)
    • deployment directory (webapps in Tomcat)
  • upgrade hardware. use faster CPU and RAM, better internet connection (for downloading dependencies) and database connection, switch to SSD. a video card doesn't matter.

WARNINGS

  1. the first option comes for the price of reduced security.
  2. the second option costs money (obviously).

To me it sounds like you're using a wrong configuration setting. Start by checking myContainer and possible conflicts. To determine who is using the most resources you have to check the memory maps (see the amount of data!) for each dependency at a time - and that takes plenty of time, as well... (and SUDO privileges). By the way: are you usually testing the code against the dependencies?

참고URL : https://stackoverflow.com/questions/27230702/speed-up-spring-boot-startup-time

반응형