programing

스프링 부트 시작 시간 단축

javaba 2022. 10. 6. 21:28
반응형

스프링 부트 시작 시간 단축

Spring Boot 어플리케이션이 있다.의존관계가 많이 추가되어(불행하게도 모두 필요한 것 같습니다) 부팅 시간이 상당히 길어졌습니다.그냥 하는 거야SpringApplication.run(source, args)10초 걸립니다.

그것이 「사용되고 있는」 것에 비하면 그다지 큰 것은 아닐지 모르지만, 그 정도의 시간이 걸리는 것은, 주로 개발의 흐름을 방해하기 때문입니다.현시점에서는 어플리케이션 자체가 작기 때문에 어플리케이션 클래스 자체가 아니라 추가된 의존관계와 관련된 경우가 대부분이라고 생각합니다.

Classpath 스캔에 문제가 있다고 생각되는데, 어떻게 해야 할지 잘 모르겠습니다.

  • 이것이 문제임을 확인합니다(스프링 부트의 디버깅 방법).
  • 진짜 원인이라면 어떻게 하면 더 빨리 할 수 있을까요?예를 들어 일부 종속성 또는 패키지에 Spring이 스캔해야 할 내용이 포함되어 있지 않은 경우 이를 제한할 수 있는 방법이 있습니까?

기동시에 병렬 빈의 초기화를 가지는 Spring을 강화하면, 작업이 고속화된다고 생각합니다만, 그 강화 요구는 2011년부터, 아무런 진척 없이 오픈되고 있습니다.Spring Boot 자체에는 Investigate Tomcat JarScaning 속도 향상과 같은 몇 가지 다른 노력이 있지만, 이는 Tomcat에 따라 다르며 포기되었습니다.

이 기사:

통합 테스트를 목적으로 하지만, 을 사용할 것을 제안합니다.lazy-init=true단, Java 설정을 사용하여 Spring Boot의 모든 콩에 적용하는 방법은 알 수 없습니다.여기에 포인트가 있나요?

어떤 제안이라도 환영합니다.

스프링 부트에서는 불필요한 자동 설정이 많이 이루어집니다.따라서 앱에 필요한 자동 구성만 좁힐 수 있습니다.포함된 자동 구성 전체 목록을 보려면 로깅을 실행하십시오.org.springframework.boot.autoconfigure디버깅 모드(logging.level.org.springframework.boot.autoconfigure=DEBUGapplication.properties)의 다른 옵션은 spring boot 어플리케이션을 실행하는 것입니다.--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 프로젝트가 실행됩니다.저는 Spring Boot 어플리케이션의 기동시간을 측정할 수 있도록 설계했습니다.이것에 의해 생성되는 실행 가능한 jar를 사용합니다.bootJar(이전에는bootRepackagegradle 작업을 수행합니다.자유롭게 사용하시고 피드백을 주세요.

저의 조사결과는 다음과 같습니다.

  1. CPU가 중요합니다.많습니다.
  2. -Xverify:none을 사용하여 JVM을 시작하면 큰 도움이 됩니다.
  3. 불필요한 자동 설정을 제외하는 것이 도움이 됩니다.
  4. Dave는 JVM 인수 -XX를 추천했습니다.Tiered StopAtLevel=1이지만 테스트 결과 크게 개선되지 않았습니다.또한.-XX:TieredStopAtLevel=1아마 첫 번째 요청이 느려질 겁니다.
  5. 호스트명 해결이 느리다는 보고가 있었습니다만, 테스트한 앱에서는 문제가 되지 않았습니다.

스프링 부트 2.2M1은 스프링 부트에서의 레이지 초기화를 지원하는 기능을 추가했습니다.

디폴트로는 응용 프로그램콘텍스트가 갱신되면 콘텍스트 내의 모든 빈이 작성되어 의존관계가 주입됩니다.반면 빈 정의가 느릿느릿 초기화되도록 구성된 경우 빈 정의는 생성되지 않으며 필요할 때까지 종속성이 주입되지 않습니다.

레이지 초기화 세트의 이니블화spring.main.lazy-initialization사실대로

레이지 초기화를 유효하게 하는 경우

느린 초기화는 시작 시간을 크게 단축할 수 있지만 몇 가지 단점도 있으므로 주의하여 활성화하는 것이 중요합니다.

자세한 내용은 문서를 참조하십시오.

업데이트:

스프링 부트 스프링 부트 2.4.0 - 스타트업 엔드포인트

Spring Boot 2.4.0에서는 시작까지 예상보다 오래 걸리는 콩을 식별하기 위해 사용할 수 있는 새로운 스타트업 엔드포인트가 추가되었습니다.응용 프로그램 시작 추적에 대한 자세한 내용은 여기를 참조하십시오.

이 질문/답변에서 설명한 바와 같이, 가장 좋은 접근법은 자신이 필요하다고 생각하는 것만 추가하는 것이 아니라, 필요 없다고 생각하는 의존관계를 배제하는 것이라고 생각합니다.

참조: 스프링 부트 시작 시간 최소화

요약:

명령줄에서 응용 프로그램을 시작할 때 --debug를 지정하기만 하면 간단히 디버깅 로깅을 활성화할 수 있습니다.application.properties에서 debug=true를 지정할 수도 있습니다.

또한 application.properties에서 다음과 같이 로깅 수준을 설정할 수 있습니다.

logging.level.org. springframework.Web: DEBUG logging.level.org.debugate: ERERROR

불필요한 자동 설정 모듈을 검출했을 경우는, 무효로 할 수 있습니다.이에 대한 문서는 http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/ #using-boot-boot-specific-auto-configuration에서 찾을 수 있습니다.

예를 들어 다음과 같습니다.

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

여기에서는 가능한 액션의 전체 목록을 설명하고 있습니다.https://spring.io/blog/2018/12/12/how-fast-is-spring

Spring 쪽에서 가장 중요한 메모를 넣겠습니다(조금 조정).

  • Spring Boot Web Starters로부터의 클래스 경로 제외:
    • 휴지 상태 검증기
    • Jackson(단, 스프링 부츠 액추에이터에 의존함).JSON 렌더링이 필요한 경우 Gson을 사용합니다(초기 MVC에서만 사용 가능).
    • 로그백: 대신 slf4j-jdk14 사용
  • spring-context-indexer 를 사용합니다.별로 도움이 되진 않겠지만, 작은 도움도 많이 줄 거야.
  • 액튜에이터를 사용하지 않을 여유가 있다면 사용하지 마십시오.
  • Spring Boot 2.1 및 Spring 5.1을 사용합니다.2.2 및 5.2를 사용할 수 있게 되면 전환합니다.
  • Spring Boot 설정 파일의 위치를 수정합니다.spring.config.location(명령줄 인수 또는 시스템 속성 등).IDE에서의 테스트 예:spring.config.location=file://./src/main/resources/application.properties.
  • JMX가 필요 없는 경우는, JMX 를 오프합니다.spring.jmx.enabled=false(이것은 Spring Boot 2.2의 디폴트입니다).
  • 기본적으로는 빈 정의를 느리게 만듭니다.새로운 깃발이 있다.spring.main.lazy-initialization=trueSpring Boot 2.2(사용)LazyInitBeanFactoryPostProcessor더 오래된 봄용)
  • 뚱뚱한 병의 포장을 풀고 명시적인 클래스 패스로 달립니다.
  • JVM을 실행하다-noverify.또한 고려사항-XX:TieredStopAtLevel=1(이렇게 하면 나중에 JIT의 속도가 느려집니다만, 기동 시간이 절약됩니다.

상기의LazyInitBeanFactoryPostProcessor(플래그를 적용할 수 없는 경우 Spring 1.5에서 사용할 수 있습니다.spring.main.lazy-initialization=trueSpring 2.2부터 이용 가능):

public class LazyInitBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      for (String beanName : beanFactory.getBeanDefinitionNames()) {
        BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
        definition.setLazyInit(true);
      }
  }
}

또, 콩의 초기화 시간을 분석하려면 , https://github.com/lwaddicor/spring-startup-analysis 를 사용할 수도 있습니다(또는 직접 작성할 수도 있습니다.

도움이 됐으면 좋겠다!

수동 테스트를 위해 개발 턴어라운드를 최적화하려는 경우 devtools 사용을 강력히 권장합니다.

클래스 경로의 파일이 변경될 때마다 spring-boot-devtools를 사용하는 응용 프로그램이 자동으로 재시작됩니다.

다시 컴파일하기만 하면 서버가 자동으로 재시작됩니다(Groovy의 경우 소스 파일만 업데이트하면 됩니다).IDE(예를 들어 'vscode')를 사용하는 경우 Java 파일을 자동으로 컴파일할 수 있으므로 Java 파일을 저장하는 것만으로 간접적으로 서버 재시작을 시작할 수 있으며, Java도 Groovy와 같은 심리스 상태가 됩니다.

이 방법의 장점은 증분 재시작을 통해 스크래치 시작 단계 중 일부가 단락되므로 서비스가 훨씬 빠르게 복구되고 실행될 수 있다는 것입니다.


그러나 이 방법은 도입 시작 시간이나 자동 장치 테스트에는 도움이 되지 않습니다.

경고: 자동 DB 스키마 생성에 Hibernate DDL을 사용하지 않고 L2 캐시를 사용하지 않는 경우 이 답변은 적용되지 않습니다.앞으로 스크롤합니다.

Hibernate는 어플리케이션 부팅에 상당한 시간을 할애한다는 것을 알게 되었습니다.L2 캐시 및 데이터베이스 초기화를 비활성화하면 Spring Boot 앱 부팅 속도가 빨라집니다.운영 환경에서는 캐시를 켜두고 개발 환경에서는 사용하지 않도록 설정하십시오.

application.yml:

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

테스트 결과:

  1. L2 캐시가 켜져 있고ddl-auto: update: 54초

     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 캐시가 꺼지고ddl-auto: none: 32초

     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)
    

22초 늘었어!이제 나는 이 모든 자유시간을 무엇을 할지 궁금하다.

이전에는 아무도 이러한 최적화를 제안하지 않은 것이 이상하다고 생각합니다.다음은 개발 시 프로젝트 구축 및 시작을 최적화하는 일반적인 힌트입니다.

  • 바이러스 대책 스캐너에서 개발 디렉토리를 제외합니다.
    • 프로젝트 디렉토리
    • 출력 디렉토리를 빌드합니다(프로젝트 디렉토리 외부에 있는 경우).
    • IDE 인덱스 디렉토리(예: ~/).인텔리 JIdea 2018.3)
    • 전개 디렉토리(Tomcat의 webapp)
  • 하드웨어를 업그레이드합니다.더 빠른 CPU와 RAM, 더 나은 인터넷 연결(의존관계 다운로드용) 및 데이터베이스 연결을 사용하여 SSD로 전환합니다(현재는 NVMe SSD가 가장 성능이 뛰어난 스토리지입니다).비디오 카드는 문제가 되지 않습니다.
  • 최신 Gradle 및 JVM 버전을 사용합니다.출처: 간단한 성능 향상.
  • 병렬 실행더 많은 동시 프로세스를 사용함으로써 병렬 빌드는 전체 빌드 시간을 크게 단축할 수 있습니다.

경고.

  1. 첫 번째 옵션은 보안 감소의 가격입니다.
  2. 두 번째 옵션은 비용이 듭니다.

저 같은 경우에는 브레이크 포인트가 너무 많았어요.음소거 중단점을 클릭하고 디버깅 모드로 응용 프로그램을 다시 시작하니 응용 프로그램이 10배 빠르게 실행되었습니다.

잘못된 설정을 사용하고 계신 것 같습니다.먼저 myContainer와 가능한 충돌을 확인합니다.누가 가장 많은 리소스를 사용하고 있는지 판단하려면 메모리 맵(데이터 양 참조)을 한 번에 각 종속성에 대해 확인해야 합니다.이 작업에도 많은 시간이 걸립니다.(및 SUDO 권한).그런데, 당신은 보통 의존관계에 대해 코드를 테스트하고 있습니까?

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

반응형