반응형
해당 글에서는 스케줄링에 대해 이해하고 Spring Boot Starter Quartz를 이용하여 스케줄링을 구성하는 간단한 예시를 구성하는 방법을 위한 목적으로 작성한 글입니다.
💡 스케줄러를 이해하기 이전에 Spring Boot Batch에 알고 싶으시면 아래의 글을 참고하시면 크게 도움이 됩니다.
1) 스케줄링(Scheduling) & 배치 스케줄링(Batch Scheduling)
💡 스케줄링(Scheduling) 이란?
- 일정한 시간 간격으로 반복적인 작업을 수행하는 도구를 의미합니다.
- 스케줄링을 이용하면 작업을 자동으로 수행하거나 주기적 혹은 일정 시간이 지난 후에 작업을 수행할 수 있어서 효율적인 작업 관리가 가능합니다.
💡 배치 스케줄링(Batch Scheduling) 이란?
- 배치 프로그램은 ‘대량의 데이터를 처리하는 작업을 자동화’하는 프로그램을 의미합니다.
- 이 대량의 데이터를 정해진 일정 또는 특정 이벤트 발생시간에 자동화 처리를 하기 위한 것’을 의미합니다.
[ 더 알아보기 ]
💡 배치 프로그램과 스케줄러는 동일한 것인가?
- 비슷한 기능을 가지고 있지만 동일한 것은 아닙니다. 실행방법과 목적에 큰 차이가 있습니다.
- 배치 프로그램은 일괄 처리를 위한 프로그램이며 정해진 시간에 실행되지 않고 사용자의 명령이 있을 때 실행합니다.
- 스케줄러는 정해진 시간에 자동으로 실행되는 프로그램이며 주기적으로 실행되는 작업을 설정할 수 있습니다.
2) 내부 클래스를 이용한 스케줄링
💡 Java에서는 다양한 스케줄링 기능을 제공하는 클래스들이 존재합니다.
- 그중에서도 가장 많이 사용되는 스케줄러 클래스는 'Timer' 및 'ScheduledExecutorService'입니다.
- 이들 클래스는 각각 다른 방식으로 스케줄링 기능을 제공합니다.
1. Timer 클래스를 이용한 스케줄링
💡 java.util.Timer 란?
- 해당 클래스를 이용하여 ‘특정한 시간 간격으로 작업을 수행하도록 예약’할 수 있습니다.
- Timer 클래스는 TimerTask 객체를 스케줄링하는 데 사용됩니다. TimerTask 객체는 Timer 클래스가 실행되는 스레드에서 실행되며 주어진 시간 이후에 수행됩니다.
메서드 | 설명 |
schedule(TimerTask task, long delay) | 주어진 시간(delay) 이후에 작업(task)을 수행합니다. |
schedule(TimerTask task, long delay, long period) | 주어진 시간(delay) 이후에 작업(task)을 수행하고 이후 일정 시간(period) 간격으로 작업(task)을 반복해서 수행합니다. |
schedule(TimerTask task, Date time) | 주어진 시간(time)에 작업(task)을 수행합니다. |
schedule(TimerTask task, Date firstTime, long period) | 주어진 시간(firstTime)에 작업(task)을 수행하고, 이후 일정 시간(period) 간격으로 작업(task)을 반복해서 수행합니다. |
💡 간단 예시 설명
- Timer의 객체를 구성하며 TimerTask 클래스를 상속받은 클래스를 생성하여 run() 메서드를 오버라이드합니다.
- run() 메서드 안에서 실행하고자 하는 작업을 작성하며 schedule() 메서드를 호출하여 작업을 예약합니다.
import java.util.Timer;
import java.util.TimerTask;
public class SchedulerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
System.out.println("Task executed after 5 seconds");
}
};
timer.schedule(task, 5000);
}
}
2. ScheduledExecutorService 인터페이스를 이용한 스케줄링
💡 java.util.concurrent.ScheduledExecutorService 란?
- java.util.concurrent 패키지에서 제공하며 Java에서 스케줄러를 사용하기 위한 기본적인 인터페이스입니다.
- ScheduledExecutorService를 사용하면 특정 시간에 작업을 실행하거나 주기적으로 작업을 실행하는 등의 스케줄링이 가능합니다
메서드 | 설명 |
schedule(Runnable command, long delay, TimeUnit unit) | 지정된 지연 시간 후에 한 번만 작업을 실행합니다. |
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) | 지정된 초기 지연 후에 첫 번째 작업을 실행하고, 이후에는 지정된 주기마다 작업을 실행합니다. |
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) | 지정된 초기 지연 후에 첫 번째 작업을 실행하고, 이후에는 이전 작업이 완료된 시점부터 지정된 지연 시간이 경과한 후에 작업을 실행합니다. |
💡 간단 예시 설명
- 해당 예시에서는 3개의 작업을 스케줄링하고 있는 예시입니다.
- 첫 번째 스케줄링은 5초 후에 "Hello World!"를 출력하는 예시입니다.
- 두 번째 스케줄링은 1초 후부터 3초마다 "Fixed Rate"를 출력하는 예시입니다.
- 세 번째 스케줄링은 이전 작업이 완료된 후 2초 후에 "Fixed Delay"를 출력하는 예시입니다.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SchedulerExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
// 5초 후에 실행되는 작업
executor.schedule(() -> System.out.println("Hello World!"), 5, TimeUnit.SECONDS);
// 1초 후부터 3초마다 실행되는 작업
executor.scheduleAtFixedRate(() -> System.out.println("Fixed Rate"), 1, 3, TimeUnit.SECONDS);
// 이전 작업이 완료된 후 2초 후에 실행되는 작업
executor.scheduleWithFixedDelay(() -> System.out.println("Fixed Delay"), 0, 2, TimeUnit.SECONDS);
}
}
3) Spring Boot Quartz
💡 Quartz란?
- Java 기반의 오픈 소스 작업 '스케줄링 라이브러리'를 의미합니다. 이를 사용하면 특정시간에 작업을 실행하거나 특정 간격으로 작업을 수행할 수 있습니다.
- 이를 사용하면 시스템의 자동화 및 효율성 향상에 기여하며 백그라운드 작업을 수행하는 서비스, 이메일 발송 스케줄링, 데이터베이스 백업 등에 활용될 수 있습니다.
[참고] Baeldung : Introduction to Quartz
Introduction to Quartz | Baeldung
4) Quartz의 기능과 사용목적
1. Quartz의 기능
💡 Quartz의 주요한 기능들을 확인해 봅니다.
기능 | 설명 |
작업 스케줄링 | 작업 예약 및 주기 설정 기능을 제공합니다 |
작업 실행 및 관리 | 작업 실행, 중단, 재개, 삭제 기능을 제공합니다 |
작업 중단 및 재개 | 작업 중단, 재개 기능을 제공합니다 |
여러 작업 동시 실행 | 동시에 여러 작업 실행 기능을 제공합니다 |
작업 실행 결과 처리 | 작업 실행 결과 처리 기능을 제공합니다 |
2. Quartz의 사용 목적
💡 Quartz의 사용 목적에 대해서 확인해 봅니다.
분류 | 사용목적 내용 |
쉬운 작업 구현 | 스케줄링, 예약, 실행, 관리 등의 작업을 쉽게 구현할 수 있습니다. |
다양한 작업 예약 및 실행 | 다양한 작업을 예약하고 실행할 수 있습니다. |
작업 실행 결과 처리 및 기록 | 작업 실행 결과를 처리하고 이를 기록할 수 있습니다. |
다양한 트리거 지원 | 다양한 트리거(trigger)를 지원합니다. |
무료 사용 | 오픈 소스이기 때문에 무료로 사용할 수 있습니다. |
5) Quartz 클래스 및 인터페이스
💡 Quartz에서는 Job과 Trigger를 함께 사용하여 Scheduler에 작업을 예약하고 Quartz는 자동으로 실행하도록 설정합니다.
1. 클래스 및 인터페이스
용어 | 설명 |
Job | 실행할 작업에 대한 정보를 포함하는 클래스 |
JobDetail | Job 클래스의 인스턴스와 Job 실행에 필요한 추가 정보를 포함하는 클래스 |
Trigger | Job 실행을 스케줄링하기 위한 클래스 |
SimpleTrigger | 지정된 시간 간격으로 Job을 실행하기 위한 Trigger |
CronTrigger | Cron 표현식으로 Job을 스케줄링하기 위한 Trigger |
Scheduler | Job 실행과 Trigger 스케줄링을 관리하는 인터페이스 |
SchedulerFactory | Scheduler 인스턴스를 생성하고 구성하기 위한 인터페이스 |
2. Job
💡 Job 이란?
- Quarz에서 ‘실행할 작업을 정의’하는 인터페이스입니다.
- Job 인터페이스를 구현하여 자신이 실행하고자 하는 작업에 대해서 정의를 할 수 있으며 Quartz의 생명 주기에 따라 주기적으로 실행이 됩니다.
3. Trigger
💡 Trigger 란?
- ‘Job을 실행시키는 조건을 정의’하는 인터페이스입니다.
- 이를 통해 Job을 특정 시간에 실행하거나 주기적으로 실행하도록 설정할 수 있습니다.
트리거 | 설명 |
SimpleTrigger | 특정 시간 또는 주기적으로 한 번 실행되는 트리거입니다. |
CronTrigger | Cron 표현식을 사용하여 특정 시간에 실행되는 트리거입니다. |
CalendarIntervalTrigger | 지정된 간격으로 주기적으로 실행되는 트리거입니다. |
DailyTimeIntervalTrigger | 지정된 시간 범위 내에서 지정된 간격으로 주기적으로 실행되는 트리거입니다. |
4. Scheduler
💡 Scheduler 란?
- Job과 Trigger를 ‘연결’하고 Job을 ‘실행 시’ 키는 역할을 수행하는 인터페이스입니다,
메서드 | 설명 |
schedule(JobDetail jobDetail, Trigger trigger) | JobDetail과 Trigger를 사용하여 Job을 스케줄링합니다. |
scheduleJob(JobDetail jobDetail, Trigger trigger) | schedule()과 같이 JobDetail과 Trigger를 사용하여 Job을 스케줄링합니다. |
scheduleJob(Trigger trigger) | JobDetail 없이 Trigger만 사용하여 Job을 스케줄링합니다. |
rescheduleJob(TriggerKey triggerKey, Trigger newTrigger) | 지정된 Trigger의 스케줄을 업데이트합니다. |
unscheduleJob(TriggerKey triggerKey) | 지정된 Trigger를 해제하여 Job 스케줄링을 취소합니다. |
pauseTrigger(TriggerKey triggerKey) | 지정된 Trigger를 일시 중지합니다. |
resumeTrigger(TriggerKey triggerKey) | 지정된 Trigger를 다시 시작합니다. |
pauseJob(JobKey jobKey) | 지정된 Job을 일시 중지합니다. |
resumeJob(JobKey jobKey) | 지정된 Job을 다시 시작합니다. |
6) Trigger 상세
1. SimpleTrigger
💡 SimpleTrigger란?
- ‘특정 시간에 한 번 실행’하거나 ‘주기적으로 실행’할 수 있습니다.
- 예를 들어, "매일 9시에 실행" 또는 "10초마다 실행"과 같은 작업을 예약할 수 있습니다
속성 | 설명 |
repeatCount | 작업이 실행될 횟수를 지정합니다. 음이 아닌 정수 값이 될 수 있습니다. 0이 입력되면 작업이 무한히 실행됩니다. |
repeatInterval | 작업이 실행되는 간격을 지정합니다. 밀리초 단위로 측정될 수 있는 어떤 정수 값이든 될 수 있습니다. |
💡 사용 예시
- Job이 시작 시간(startTime)부터 10초 간격으로 5번 실행됩니다. repeatCount를 0으로 지정하면 무한히 실행됩니다.
SimpleTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(startTime)
.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(5))
.build();
2. CronTrigger
💡 CronTrigger란?
- Cron 표현식을 사용하여 ‘지정된 시간에 작업을 예약’할 수 있습니다.
- Cron 표현식은 분, 시, 일, 월, 요일 등의 필드를 사용하여 작업을 예약할 수 있습니다.
- 예를 들어, "월요일부터 금요일까지, 매일 오후 3시에 실행"과 같은 작업을 예약할 수 있습니다.
속성명 | 설명 |
cronExpression | Cron 표현식을 나타내는 문자열입니다. 이 표현식은 CronTrigger가 실행될 시간을 정의합니다. |
timeZone | CronTrigger가 실행될 때 사용할 시간대를 나타내는 문자열입니다. 이 속성을 설정하지 않으면 기본값으로 서버의 시간대가 사용됩니다. |
misfireInstruction | CronTrigger가 실행되지 않은 경우 동작을 지정하는 데 사용되는 상수입니다. 예를 들어, misfireInstruction을 MISFIRE_INSTRUCTION_FIRE_ONCE_NOW로 설정하면 CronTrigger가 다음 실행 시간에 실행됩니다. |
priority | 트리거의 우선 순위를 나타내는 숫자입니다. 높은 우선 순위 값을 가진 트리거는 낮은 우선 순위 값을 가진 트리거보다 먼저 실행됩니다. |
💡 사용 예시
- 다음은 매주 월요일 오전 10시에 실행되는 CronTrigger의 예시입니다.
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 10 ? * MON"))
.build();
2.1. Cron 표현식
💡 Cron 표현식은 리눅스 시스템에서 주기적인 작업을 자동으로 수행하기 위해 사용되는 문법입니다.
💡 cron 표현식 구성
- 분, 시, 일, 월, 요일 순서로 입력됩니다.
* * * * *
- - - - -
| | | | |
| | | | +----- 요일 (0 - 6) (0이나 7이 일요일)
| | | +---------- 월 (1 - 12)
| | +--------------- 일 (1 - 31)
| +-------------------- 시 (0 - 23)
+------------------------- 분 (0 - 59)
💡 cron 표현식 예시
Cron Expression | 설명 |
* * * * * | 매 분 |
*/30 * * * * | 30분마다 |
30 5 * * * | 매일 오전 5시 30분 |
30 5 * * 1 | 매주 월요일 오전 5시 30분 |
30 5 1 * * | 매월 1일 오전 5시 30분 |
7) Quartz의 실행주기
💡 Quartz의 실행되는 단계입니다.
단계 | 분류 | 설명 |
1 | 스케줄러 초기화 | Quartz 스케줄러는 시작되면 먼저 스케줄러를 초기화합니다. 이 초기화 과정에서는 스케줄러에 대한 설정을 로드하고, 자바 애플리케이션 컨텍스트와 연결합니다. |
2 | 작업 스케줄링 | Quartz 스케줄러는 작업 스케줄링을 수행합니다. 이 과정에서는 사용자가 등록한 작업을 실행할 시간을 계산하여 스케줄링 테이블에 등록합니다. |
3 | 작업 실행 | 스케줄링 된 작업이 실행됩니다. Quartz 스케줄러는 스케줄링 된 작업을 실행하기 위해 쓰레드 풀을 사용합니다. |
4 | 작업 완료 | 작업이 완료되면 Quartz 스케줄러는 작업이 완료되었다는 신호를 받습니다. 이 신호를 받으면 스케줄링 테이블에서 작업을 제거합니다. |
5 | 스케줄러 종료 | Quartz 스케줄러는 애플리케이션 종료 시점에 스케줄러를 종료합니다. 이 과정에서는 스케줄링 된 작업을 모두 제거하고, 쓰레드 풀을 종료합니다. |
8) 테스트 개발환경 및 사용 예시
1. 테스트 개발환경
💡 개발환경에서는 ‘spring-boot-starter-quartz’ 라이브러리를 의존성으로 추가하여서 구성하였습니다.
개발환경 | 버전 |
java | 11 |
Spring Boot | 2.7.5 |
빌드관리도구 | Gradle 7.5 |
개발 툴 | IntelliJ IDEA 2022.3 |
spring-boot-starter-quartz | 2.7.5 |
Maven Repository: org.springframework.boot » spring-boot-starter-quartz
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-quartz:2.7.5' // Spring Boot Quartz
}
2. 사용 예시
💡 간단 예시 설명
- 아래 코드는 매 10초마다 "Hello Quartz!"를 출력하는 Job을 실행하는 예시입니다.
- Job과 Trigger를 생성합니다.
- 이를 통해서 스케줄러를 생성하고 Job과 Trigger로 구성합니다.
- 최종적으로 스케줄러 작업을 구성합니다.
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzExample {
public static void main(String[] args) throws SchedulerException {
// Job 생성
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("myJob", "group1")
.build();
// Trigger 생성
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10)
.repeatForever())
.build();
// 스케줄러 생성 및 Job, Trigger 등록
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
}
}
// 실행할 Job 클래스
public class MyJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello Quartz!");
}
}
💡 [참고] Spring Boot Quartz에 대해 상세한 내용은 다음 글에서 이어집니다.
오늘도 감사합니다. 😀
반응형
'Java > Spring Boot' 카테고리의 다른 글
[Java] Spring Boot OAuth 2 Client 이해하기 -1 : 정의, 흐름, 인증방식 종류 (0) | 2023.07.09 |
---|---|
[Java] Spring Cloud 이해하기 -1 : 주요 특징으로 이해하기 (0) | 2023.06.19 |
[Java] Spring Boot Batch 이해하고 설정하기 -1 : 정의 및 이해 (2) | 2023.04.22 |
[Java] Spring Boot Cache 이해하고 설정하기 -2 : 사용 및 활용 예시 (0) | 2023.04.16 |
[Java] Spring Boot Cache 이해하고 설정하기 -1 : 정의, 환경 설정 (2) | 2023.04.16 |