[Spring boot] @Scheduled 어노테이션을 사용한 스케줄링이 작동하지 않는 문제 해결
Spring에서 주기적으로 작업을 실행하고 싶을 때 @Scheduled 어노테이션을 사용하면 매우 유용합니다. 예를 들어, Redis 큐에서 일정 시간 간격으로 메시지를 처리해야 할 때 @Scheduled을 활용해 스케줄링을 구현할 수 있습니다. 하지만, 이 어노테이션을 사용했음에도 불구하고 메서드가 주기적으로 실행되지 않는 문제가 발생할 수 있습니다.
문제 상황
다음은 @Scheduled 어노테이션을 사용하여 Redis 큐에서 메시지를 2초마다 가져오는 작업을 수행하는 코드입니다
@Component
@RequiredArgsConstructor
@Slf4j
public class TourQueueScheduler {
private final TourQueueProcessor tourQueueProcessor;
@Scheduled(fixedDelay = 2000)
public void consumeMessages() {
String queueName = "tourRequest";
log.info("Consuming messages from queue: {}", queueName);
tourQueueProcessor.processMessage(queueName);
}
}
이 코드에서 @Scheduled(fixedDelay = 2000)을 사용하여 2초마다 consumeMessages 메서드를 호출하려 했지만, 스케줄링이 전혀 실행되지 않는 문제에 직면했습니다.
원인
1. @EnableScheduling 미등록
@Scheduled 어노테이션을 사용하려면 @EnableScheduling 어노테이션이 필수적으로 필요합니다. Spring은 기본적으로 스케줄링 기능을 자동으로 활성화하지 않기 때문에, 이 어노테이션을 명시적으로 선언해줘야 합니다. 이를 선언하지 않으면 스케줄링 기능이 활성화되지 않으며, @Scheduled이 적용된 메서드는 실행되지 않습니다.
2. @Scheduled 메서드의 접근 제어자 문제
또 다른 실수는 @Scheduled 어노테이션이 적용된 메서드가 public 접근 제어자를 가져야 한다는 점입니다. 만약 protected나 private 접근 제어자를 사용할 경우, 메서드는 실행되지 않으며, 오류 없이 스케줄링이 작동하지 않습니다.
해결 방법
1. @EnableScheduling 어노테이션을 main 클래스에 추가하여 스케줄링 기능을 활성화합니다.
2. @Scheduled이 적용된 메서드에는 이미 public 접근 제어자로 설정했습니다.
@EntityScan(basePackages = "entity")
@SpringBootApplication
@EnableScheduling // 스케줄링 활성화
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
@Scheduled 어노테이션을 사용할 때, 스케줄링이 동작하지 않는 이유는 주로 @EnableScheduling 어노테이션이 누락되었거나, 메서드의 접근 제어자가 적절하지 않기 때문입니다. 이 두 가지를 점검하고 수정하면 스케줄링 작업이 정상적으로 실행될 것입니다.