본문 바로가기

Study Information Technology

스프링 부트의 Scheduled 어노테이션으로 스케줄링 구현하기

728x90
반응형

스프링 부트의 @Scheduled 어노테이션으로 스케줄링 구현하기

Overview

스프링 부트는 강력한 스케줄링 기능을 제공하여 애플리케이션에서 주기적으로 작업을 수행할 수 있게 해줍니다. @Scheduled 어노테이션을 사용하면 개발자가 직접 시간을 설정하여 특정 메서드를 주기적으로 실행할 수 있습니다. 이는 백그라운드 작업, 데이터베이스 정리, 외부 API 호출 등 다양한 상황에서 유용하게 사용됩니다. 이번 글에서는 @Scheduled 어노테이션을 사용한 스케줄링의 원리와 구현 방법에 대해 자세히 설명하겠습니다.

스케줄링의 기본 원리

스프링의 스케줄링은 일반적으로 애플리케이션의 생명 주기와 함께 동작합니다. @Scheduled 어노테이션이 붙은 메서드는 스프링이 관리하는 스레드 풀에 의해 관리되며, 설정된 주기에 맞춰 호출됩니다.

주기적 작업 실행

  • Fixed Rate: 지정된 시간 간격으로 작업이 실행됩니다. 이전 작업이 완료된 시점과 관계없이 설정된 주기에 맞춰 실행됩니다.
  • Fixed Delay: 이전 작업이 완료된 후, 설정된 지연 시간 후에 다음 작업이 실행됩니다.
  • Cron 표현식: 더 복잡한 스케줄링을 위해 Cron 표현식을 사용할 수 있습니다. 이 방법은 특정 시간, 날짜, 주 등을 기준으로 작업을 실행할 수 있게 해줍니다.

구현 방법

1. 스프링 부트 프로젝트 설정

먼저, 스프링 부트 프로젝트를 설정합니다. Spring Initializr(https://start.spring.io/)를 통해 새로운 프로젝트를 생성하고, Spring WebSpring 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 어노테이션을 사용하면 간단하고 효율적으로 주기적인 작업을 수행할 수 있습니다. 여러 가지 스케줄링 옵션을 통해 유연하게 작업을 설정할 수 있으며, 예외 처리와 비동기 실행을 통해 안정성을 높일 수 있습니다. 이러한 기능은 다양한 비즈니스 로직에서 유용하게 활용될 수 있습니다.

참고문서

반응형