TIL

Java Spring Scheduler 정의 및 사용법 예시

빈코 2024. 9. 13. 15:57

 

스케줄러 설정

 

개요

웹 사이트를 운영하다 보면 주기적으로 특정 작업을 해야 할 때가 있습니다. 예를 들어, 매월 마지막 날에 어떤 통계를 내야 한다던지, 매일 쌓이는 로그를 지정해 둔 사이즈에 도달했을 때 순차적으로 삭제하는 등의 작업들입니다. 개발자가 직접적으로 해당 시간마다 작업을 진행할 수 없기에 Java에서는 Scheduler라는 기능을 제공합니다. 아래에서 좀 더 자세히 살펴볼까요?

 

Spring Scheduler 란?📙

Java Spring Scheduler는 개요에서 설명한 바와 같이 스프링 프레임워크에서 제공하는 작업 스케줄링 기능입니다. 

 

해당 기능을 통해 개발자는 지정된 시간 간격이나 특정 시점에 자동으로 실행되어야 하는 작업을 쉽게 구성할 수 있고, 스프링 스케줄러는 멀티스레딩비동기 실행을 지원하여 효율적인 백그라운드 작업 처리를 제공합니다.

 

이를 통해 서버가 지속적으로 요청을 받으면서도 배치 작업이나 주기적인 작업을 동시에 수행할 수 있는 강점이 있습니다.

 

설정 방법은 크게 2가지가 있는데, 사실 지금은 Spring Boot로 넘어가는 추세라 1가지를 대중화하여 사용합니다. 보다 자세한 내용은 하위에서 살펴보겠습니다 :)

Spring Scheduler  설정 방법 2가지📘

Scheduler를 설정하는 방법은 총 2가지가 있습니다. 사실, 지금 시점에서는 대부분 Spring 5.x 버전을 사용하기 때문에 어노테이션으로 설정하지만, 이전에는 servlet-context.xml에 직접 Bean으로 등록 했어야 했습니다.

 

💡 Spring 버전 별 차이

  • Spring 3.x ~ 4.x : XML 기반 설정이 더 일반적이었으며,  <task:annotation-driven> 방식이 널리 사용 되었다.
  • Spring 4.x ~ 5.x : Java 기반 설정 방식(@EnableScheduling)이 더욱 선호되기 시작했으며, XML 설정이 줄어드는 추세가 되었다.
  • Spring Boot : XML 대신 Java 설정을 선호하는 트렌드가 강화되었으며, 대부분의 설정이 어노테이션을 통해 이루어졌다. @EnableScheduling

 

1. servlet-context.xml에 직접 Bean 등록하기

<!-- Scheduler -->
<context:component-scan base-package="com.test.scheduler" />
<task:scheduler id="testScheduler" pool-size="10" />
<task:annotation-driven scheduler="testScheduler" />

 

XML 기반 설정은 <task:scheduler>와 <task:annotaion-driven> 태그를 사용하여 XML 파일에서 스케줄러를 설정합니다. 여기서 <task:scheduler>는 스케줄러 빈을 정의하고, pool-size로 스레드 풀 크기를 지정할 수 있습니다. 그리고 <task:annotaion-driven> 태그를 이용하여 스케줄러를 활성화하고, 특정 스케줄러를 지정합니다.

 

 

2. @EnableScheduling 어노테이션 사용하기

첫 번째로, 스프링 애플리케이션을 실행할 main에 @EnableScheduling 어노테이션을 추가합니다.

@EnableScheduling
@SpringBootApplication
public class TestSchedulerApplication {
	public static void main(String[] args) {
    	SpringApplication.run(TestSchedulerApplication.class, agrs);
    }
}

 

두 번째로, 스케줄을 실행 할 클래스에 @Componet 어노테이션을 추가하여 스프링 빈으로 주입합니다. 그리고 @Scheduled 어노테이션을 활용하여 스케줄을 입력한 시간대에 맞게 실행하면 모든 설정이 끝이 납니다. 간단하죠?

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TestScheduler {
    
    // 매 5초마다 실행
    @Scheduled(fixedRate = 5000)
    public void scheduleTask() {
        System.out.println("스케줄 실행!");
    }
}

 

여기서 한 가지 궁금한 점이 생깁니다. 그럼 주기를 설정하는 방법은 어떤 것들이 있을까요? @Scheduled 속성에는 fixedDelay, fixedDelayString, fixedRate, fixedRateString 등 다양한 방식들이 있지만, 가장 많이 사용되는 방법은 하위에서 소개해 드릴 Cron 표현식입니다.

 

Cron 사용법📒

Cron은 특정 시간이나 주기로 작업을 예약할 때 사용하는 표현식입니다. Unix와 리눅스 환경에서 주로 사용되지만, Java의 스케줄러에서도 사용이 됩니다. 위의 코드와 같이 @Scheduled 어노테이션과 함께 사용합니다.

 

@Scheduled(cron = "0 0/1 * * * *")
... 생략

 

Cron 표현식 형식은 <초> <분> <시> <일> <월> <요일> <년도(선택적)> 으로 표현됩니다. 필드와 허용 범위 및 설명을 표로 표현하면 아래와 같습니다.

 

필드 허용 값 설명
초 (seconds) 0-59 작업 실행 시작 초
분 (minutes) 0-59 작업 실행 시작 분
시 (hours) 0-23 작업 실행 시작 시작
일 (day) 1-31 작업 실행 날짜
월 (month) 1-12 or JAN-DEC 작업 실행 월
요일 (day of week) 0-7 or SUN-SAT 작업 실행 요일
년도 (year) (생략 가능) 작업 실행 년도 (옵션)

 

// Cron 표현식 예시
"0 0 12 * * ?" // 매일 12시에 작업 실행
"0 15 10 * * ?" // 매일 10시 15분에 작업 실행
"0 0/5 14 * * ?" // 매일 14시부터 5분마다 작업 실행
"0 0 8-10 * * ?" // 매일 8시, 9시, 10시에 작업 실행
"0 0 9-17 * * MON-FRI" // 월요일부터 금요일까지 9시부터 17시까지 매 시간 작업 실행

 

마치며

지금까지 Scheduler에 대해 알아보았습니다. 설정하는 방법도 간단하고 사용법도 간단하기 때문에 어렵지 않게 적용이 가능한 기능인 것 같아요. 하지만, 가끔 스케줄러에 의해 특정 값들이 삭제되는 현상을 겪기도 해서 무분별한 스케줄링은 현업에서 좋지 않은 것 같습니다. 독자분들 모두 상황에 맞게 유용하게 사용하셨으면 합니다🙇‍♂️

 

👨‍👩‍👦‍👦 오픈채팅방 운영

취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁

 

참여코드 : 456456

https://open.kakao.com/o/gVHZP8dg

반응형