스프링 부트의 @Scheduled
어노테이션으로 스케줄링 구현하기
Overview
스프링 부트는 강력한 스케줄링 기능을 제공하여 애플리케이션에서 주기적으로 작업을 수행할 수 있게 해줍니다. @Scheduled
어노테이션을 사용하면 개발자가 직접 시간을 설정하여 특정 메서드를 주기적으로 실행할 수 있습니다. 이는 백그라운드 작업, 데이터베이스 정리, 외부 API 호출 등 다양한 상황에서 유용하게 사용됩니다. 이번 글에서는 @Scheduled
어노테이션을 사용한 스케줄링의 원리와 구현 방법에 대해 자세히 설명하겠습니다.
스케줄링의 기본 원리
스프링의 스케줄링은 일반적으로 애플리케이션의 생명 주기와 함께 동작합니다. @Scheduled
어노테이션이 붙은 메서드는 스프링이 관리하는 스레드 풀에 의해 관리되며, 설정된 주기에 맞춰 호출됩니다.
주기적 작업 실행
- Fixed Rate: 지정된 시간 간격으로 작업이 실행됩니다. 이전 작업이 완료된 시점과 관계없이 설정된 주기에 맞춰 실행됩니다.
- Fixed Delay: 이전 작업이 완료된 후, 설정된 지연 시간 후에 다음 작업이 실행됩니다.
- Cron 표현식: 더 복잡한 스케줄링을 위해 Cron 표현식을 사용할 수 있습니다. 이 방법은 특정 시간, 날짜, 주 등을 기준으로 작업을 실행할 수 있게 해줍니다.
구현 방법
1. 스프링 부트 프로젝트 설정
먼저, 스프링 부트 프로젝트를 설정합니다. Spring Initializr(https://start.spring.io/)를 통해 새로운 프로젝트를 생성하고, Spring Web
및 Spring Boot DevTools
의존성을 추가합니다. 다음으로 spring-boot-starter
에 포함된 스케줄링 기능을 사용하기 위해 @EnableScheduling
어노테이션을 추가합니다.
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. @EnableScheduling
어노테이션 추가
애플리케이션의 메인 클래스나 설정 클래스에 @EnableScheduling
어노테이션을 추가합니다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
3. 스케줄링 메서드 작성
이제 주기적으로 실행될 메서드를 작성합니다. @Scheduled
어노테이션을 사용하여 메서드에 스케줄링 정보를 추가합니다.
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
// 매 5초마다 실행
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("현재 시간: " + System.currentTimeMillis());
}
// 마지막 작업 완료 후 10초 지연 후 실행
@Scheduled(fixedDelay = 10000)
public void performTaskWithDelay() {
System.out.println("작업이 완료된 후 10초 뒤에 실행되는 작업: " + System.currentTimeMillis());
}
// 매일 자정에 실행
@Scheduled(cron = "0 0 0 * * ?")
public void performDailyTask() {
System.out.println("매일 자정에 실행되는 작업: " + System.currentTimeMillis());
}
}
4. 다양한 스케줄링 옵션 설명
Fixed Rate:
@Scheduled(fixedRate = 5000)
은 5초마다 메서드를 실행합니다. 이전 작업이 아직 실행 중인 경우, 새로운 작업이 시작될 수 있습니다. 예를 들어, 아래와 같은 출력이 발생할 수 있습니다.현재 시간: 1633036800000 현재 시간: 1633036805000 현재 시간: 1633036810000
이 경우, 이전 작업이 끝나기 전에 새로운 작업이 시작될 수 있으니 주의해야 합니다.
Fixed Delay:
@Scheduled(fixedDelay = 10000)
은 작업이 끝난 후 10초 뒤에 다음 작업이 실행됩니다. 이 방법은 이전 작업의 완료 여부를 확인할 수 있어 안정적인 처리가 가능합니다. 다음과 같은 출력이 발생합니다.작업이 완료된 후 10초 뒤에 실행되는 작업: 1633036900000 작업이 완료된 후 10초 뒤에 실행되는 작업: 1633036910000
Cron 표현식:
@Scheduled(cron = "0 0 0 * * ?")
는 매일 자정에 작업을 실행합니다. Cron 표현식은 복잡한 스케줄을 설정할 수 있어 강력합니다. 각 필드는 초, 분, 시, 일, 월, 요일 순서로 설정됩니다. 예를 들어,0 0 12 * * ?
는 매일 정오 12시에 실행됩니다.
5. 에러 처리 및 디버깅
스케줄링 메서드에서 예외가 발생하면, 해당 메서드는 더 이상 실행되지 않을 수 있습니다. 따라서 적절한 예외 처리가 필요합니다. 예를 들어, try-catch 블록을 사용하여 예외를 처리하고 로그를 남기는 방법이 있습니다.
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
try {
// 비즈니스 로직
System.out.println("현재 시간: " + System.currentTimeMillis());
} catch (Exception e) {
System.err.println("작업 수행 중 오류 발생: " + e.getMessage());
}
}
6. 성능 및 최적화
스케줄링 작업이 많아지면 성능 저하가 발생할 수 있습니다. 이때는 작업을 비동기적으로 실행하거나, 작업의 우선순위를 조절하여 리소스를 효율적으로 사용할 수 있습니다. @Async
어노테이션을 사용하면 비동기 처리가 가능합니다.
import org.springframework.scheduling.annotation.Async;
@Async
@Scheduled(fixedRate = 5000)
public void asyncScheduledTask() {
System.out.println("비동기 스케줄링 작업: " + System.currentTimeMillis());
}
이렇게 하면 스케줄링 작업이 다른 스레드에서 실행되어 애플리케이션의 응답성이 향상될 수 있습니다.
결론
스프링 부트의 @Scheduled
어노테이션을 사용하면 간단하고 효율적으로 주기적인 작업을 수행할 수 있습니다. 여러 가지 스케줄링 옵션을 통해 유연하게 작업을 설정할 수 있으며, 예외 처리와 비동기 실행을 통해 안정성을 높일 수 있습니다. 이러한 기능은 다양한 비즈니스 로직에서 유용하게 활용될 수 있습니다.
참고문서
'Study Information Technology' 카테고리의 다른 글
Spring Boot 테스트 기능 단위 테스트와 통합 테스트 (0) | 2024.10.13 |
---|---|
Spring Boot에서 커스텀 어노테이션 만들기 (0) | 2024.10.13 |
Spring Boot와 Redis를 이용한 캐싱의 성능 향상 (0) | 2024.10.13 |
OAuth2 및 OpenID Connect 구현하기 Spring Security와 Spring Boot를 활용한 애플리케이션 보안 강화 (0) | 2024.10.13 |
Spring Boot와 Prometheus Grafana 통합 실시간 모니터링과 시각화 (0) | 2024.10.13 |