Spring @Scheduled 주석이 달린 메소드는 다른 스레드에서 실행됩니까?


81

주석이 달린 몇 가지 방법이 있습니다 @Scheduled(fixedDelay=10000).

애플리케이션 컨텍스트에서 다음과 같은 주석 기반 설정이 있습니다.

<task:annotation-driven />

문제는 때때로 일부 메서드 실행이 몇 초에서 몇 분까지 지연된다는 것입니다.

메서드가 실행을 완료하는 데 시간이 걸리더라도 다른 메서드는 계속 실행될 것이라고 가정하고 있습니다. 그래서 나는 지연을 이해하지 못합니다.

지연을 줄이거 나 제거 할 수있는 방법이 있습니까?

답변:


58

완전성을 위해 아래 코드는 java 구성으로 스케줄러를 구성하는 가장 간단한 방법을 보여줍니다.

@Configuration
@EnableScheduling
public class SpringConfiguration {

    @Bean(destroyMethod = "shutdown")
    public Executor taskScheduler() {
        return Executors.newScheduledThreadPool(5);
    }
    ...

더 많은 제어가 필요한 경우 @Configuration클래스는 SchedulingConfigurer.


4
Executor인터페이스에는 shutdown()메서드 가 없기 때문에 ExecutorService빈 정의를 올바르게 만들기 위해 반환 유형으로 사용 하는 것이 좋습니다 . 아니면 Spring이 런타임에서 실제 빈 유형을 발견할까요?
Vladimir Vagaytsev

1
XML의 설정 -<task:scheduler id="taskScheduler" pool-size="5"/>
whoami를

1
SchedulingConfigurer의 예를 보려면 여기 를 참조 하십시오
crusy

1
Spring autoconfig와 함께 작동하지 않음 : 클래스 경로 리소스 [org / springframework / boot / autoconfigure / task / TaskSchedulingAutoConfiguration.class]에 정의 된 'taskScheduler'빈을 등록 할 수 없습니다. 그 이름의 빈은 이미 ... 클래스 패스 리소스에 정의 된

52

일정에 대한 문서는 말합니다 :

풀 크기 속성을 제공하지 않으면 기본 스레드 풀에는 단일 스레드 만 있습니다.

따라서 예약 된 작업이 많은 경우 문서에 설명 된대로 더 많은 스레드가있는 풀을 갖도록 스케줄러를 구성하여 하나의 긴 작업이 다른 모든 작업을 지연시키지 않도록해야합니다.


20
참고로 : 일반 문서에 대한 링크 만 제공하고 '구성'했다고 말하는 것은 도움이되지 않습니다. 예제를 제공하는 것이 훨씬 더 유용합니다. 나는 g에 투표했다. 바로이 이유 Demecki의 아래에 대답하지 당신은 ... 그냥 팁 앞서 얻을
nterry

인용 된 문서는 매개 변수 task:scheduler가있는 것을 나타냅니다 pool-size. @Scheduled풀 관련 매개 변수가없는 주석에 적용됩니까 ?
데이비드 Soroko

@DavidSoroko 나는 그렇게 믿는다.
froi

34

로 주석이 달린 메서드 @Scheduled는 한 번에 다른 스레드에서 개별적으로 실행됩니다.

TaskScheduler구성에를 제공하지 않은 경우 Spring은

Executors.newSingleThreadScheduledExecutor();

ScheduledExecutorService단일 스레드에서 실행 되는을 반환합니다 . 따라서 여러 @Scheduled메서드 가있는 경우 예약 된 경우에도 각각 스레드가 이전 작업 실행을 완료 할 때까지 기다려야합니다. 대기열이 비워지는 것보다 더 빨리 채워 지므로 계속 더 크고 더 큰 지연이 발생할 수 있습니다.

적절한 양의 스레드를 사용하여 스케줄링 환경을 구성해야합니다.


Spring 문서에 링크 하시겠습니까?
데이비드 Soroko

@DavidSoroko 이것은 Javadoc에서 즉시 명확하지 않습니다. 소스 코드에서보기가 더 쉽습니다. @Scheduled(및 @EnableScheduling)은 ScheduledAnnotationBeanPostProcessor. 이 포스트 프로세서는 ScheduledTaskRegistrar 기본적으로 단일 스레드ScheduledExecutorService .
Sotirios Delimanolis

4
나는 당신이 너무 친절하다고 생각합니다-그것은 문서에 전혀 없습니다. 소스 코드는 릴리스마다 변경 될 수 있습니다.
David Soroko 2017

24

2019 업데이트

풀 크기를 늘리는 애플리케이션 속성 파일에서 설정할 수있는 속성도 있습니다.

spring.task.scheduling.pool.size=10

Spring Boot 2.1.0부터있는 것 같습니다.


2
이것은 스프링 부트 버전> = 2.0 인 경우이를 수행하는 유일한 방법입니다. taskScheduler () 재정의는 쓸모가 없습니다
jean

10

당신이 사용할 수있는:

@Bean()
public  ThreadPoolTaskScheduler  taskScheduler(){
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(2);
    return  taskScheduler;
}

2
나는 taskScheduler.initialize();당신의 인스턴스를 반환하기 전에 전화하는 것이 좋은 관행이라고 생각합니다taskScheduler
Orby

6

@EnableScheduling 주석은 키 정보 및 해결 방법을 제공합니다 :

기본적으로는 연관된 스케줄러 정의를 검색합니다. 컨텍스트에서 고유 한 TaskScheduler 빈이거나 그렇지 않은 경우 "taskScheduler"라는 TaskScheduler 빈입니다. ScheduledExecutorService 빈에 대해서도 동일한 검색이 수행됩니다. 둘 중 어느 것도 해결할 수없는 경우 로컬 단일 스레드 기본 스케줄러가 생성되어 등록 기관 내에서 사용됩니다 .

더 많은 제어가 필요한 경우 @Configuration 클래스가 SchedulingConfigurer를 구현할 수 있습니다. 이를 통해 기본 ScheduledTaskRegistrar 인스턴스에 액세스 할 수 있습니다. 예를 들어 다음 예제는 예약 된 작업을 실행하는 데 사용되는 Executor를 사용자 지정하는 방법을 보여줍니다.

 @Configuration
 @EnableScheduling
 public class AppConfig implements SchedulingConfigurer {

     @Override
     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
         taskRegistrar.setScheduler(taskExecutor());
     }

     @Bean(destroyMethod="shutdown")
     public Executor taskExecutor() {
         return Executors.newScheduledThreadPool(100);
     }
 }

(강조 추가됨)


0

XML 파일을 사용하여 아래 줄을 추가하십시오 ..

<task:scheduler id="taskScheduler" pool-size="15" />
<task:scheduled-tasks scheduler="taskScheduler" >
....
</task:scheduled-tasks>

-1

일정 작업에 단일 스레드를 사용하는 기본 스프링. 클래스에 @Configuration을 사용하여 SchedulingConfigurer를 구현할 수 있습니다. 참조 :https://crmepham.github.io/spring-boot-multi-thread-scheduling/

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.