이번에 프로젝트에서 스케줄링을 해야하는 이벤트가 있기에 스케줄링에 대해 이해하고 Spring Boot Starter Quartz를 이용해 스케줄링을 구성해보고자 한다.
🎈 스케줄링(Scheduling)
일정한 시간 간격으로 반복적인 작업을 수행하는 도구를 의미한다.
🎈 배치 스케줄링(Batch Scheduling)
배치 프로그램은 대량의 데이터를 처리하는 작업을 자동화
하는 프로그램을 의미한다.
일괄 처리
를 위한 프로그램이며 정해진 시간에 실행되지 않고 사용자의 명령이 있을 때 실행한다.⚽ 스케줄러는 정해진 시간에 자동으로 실행되는 프로그램이며 주기적으로 실행되는 작업을 설정할 수 있다.
😉 Quartz란?
Java 기반의 오픈소스 작업 스케줄링 라이브러리
를 의미한다. 이를 사용하면 특정시간에 작업을 실행하거나 특정 간격으로 작업을 수행할 수 있다.
이를 사용하면 시스템의 자동화 및 효율성 향상에 기여하며 백그라운드 작업을 수행하는 서비스, 이메일 발송 스케줄링, 데이터베이스 백업 등에 활용될 수 있다.
작업 스케줄링
작업 실행 및 관리
작업 중단 및 재개
여러 작업 동시 실행
작업 실행 결과 처리
쉬운 작업 구현
다양한 작업 예약 및 실행
작업 실행 결과 처리 및 기록
다양한 트리거 지원
무료 사용
Quartz
에서는 Job
과 Trigger
를 함께 사용하여 Scheduler
에 작업을 예약하고 Quartz
는 자동으로 실행하도록 설정한다.용어 설명
🎈 Job
: 실행할 작업에 대한 정보를 포함하는 클래스
🎈 JobDetail
: Job 클래스의 인스턴스와 Job 실행에 필요한 추가 정보를 포함하는 클래스
Trigger
: Job 실행을 스케줄링하기 위한 클래스SimpleTrigger
: 지정된 시간 간격으로 Job을 실행하기 위한 TriggerCronTrigger
: Cron 표현식으로 Job을 스케줄링하기 위한 TriggerScheduler
: Job 실행과 Trigger 스케줄링을 관리하는 인터페이스 (JobDetail과 Trigger 정보를 이용해서 Job을 시스템에 등록하고, Trigger가 동작하면 지정된 Job을 실행시키는 역할을 하는 객체)SchedulerFactory
: Scheduler 인스턴스를 생성하고 구성하기 위한 인터페이스실행할 작업
을 정의하는 인터페이스Job 인터페이스는 execute 메서드를 정의하는데, execute 메서드의 파라미터인 JobExecutionContext에는 트리거 핸들링, 스케쥴에 의한 핸들링 등을 포함하여 런타임 환경에 대한 정보를 제공한다.
JobExecutionContext
Job
을 실행시키는 조건을 정의하는 인터페이스트리거
⚽ SimpleTrigger
: 특정 시간 또는 주기적으로 한 번 실행되는 트리거
⚽ CronTrigger
: Cron 표현식을 사용하여 특정 시간에 실행되는 트리거
⚽ CalendarIntervalTrigger
: 지정된 간격으로 주기적으로 실행되는 트리거
⚽ DailyTimeIntervalTrigger
: 지정된 시간 범위 내에서 지정된 간격으로 주기적으로 실행되는 트리거
연결
하고 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을 다시 시작한다.
특정 시간에 한 번 실행
하거나 주기적으로 실행
할 수 있다.😁 속성
repeatCount
: 작업이 실행될 횟수를 지정한다. 음이 아닌 정수 값이 될 수 있다. 0이 입력되면 작업이 무한히 실행된다.repeatInterval
: 작업이 실행되는 간격을 지정한다. 밀리초 단위로 측정될 수 있는 어떤 정수 값이든 될 수 있다.SimpleTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(startTime)
.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(5))
.build();
new Trigger()
를 통해 새로운 TriggerBuilder를 생성한다..withIdentity("trigger1", "group1")
: 트리거에 "trigger"이라는 고유한 이름과 group1이라는 그룹을 할당한다. 이를 통해 트리거를 식별하고 관리할 수 있다.startAt(startTime)
: 트리거가 작동하기 시작할 시간을 설정simpleSchedule()
: 간단한 스케줄을 설정.withIntervalInSeconds(10)
: 작업이 반복되는 간격을 초 단위로 설정 여기서는 10초마다 작업이 반복된다..withRepeatCount(5)
: 작업이 반복될 횟수를 설정. 여기서는 총 5회 반복되도록 설정즉, Job이 시작시간(startTime)부터 10초 간격으로 5번 실행된다. repeatCount를 0으로 지정하면 무한히 실행된다.
지정된 시간에 작업을 예약
할 수 있다.😁 속성명
cronExpression
: Cron 표현식을 나타내는 문자열, 이 표현식은 CronTrigger가 실행될 시간을 정의한다.timeZone
: CronTrigger가 실행될 때 사용할 시간대를 나타내는 문자열. 이 속성을 설정하지 않으면 기본값으로 서버의 시간대가 사용된다.misfireInstruction
: CronTrigger가 실행되지 않은 경우 동작을 지정하는 데 사용되는 상수. 예를 들어, misfireInstruction을 MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
로 설정하면 CronTrigger가 다음 실행 시간에 실행된다.priority
: 트리거의 우선 순위를 나타내는 숫자입니다. 높은 우선 순위 값을 가진 트리거는 낮은 우선 순위 값을 가진 트리거보다 먼저 실행된다.CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 10 ? * MON"))
.build();
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
TriggerBuilder.newTrigger()
: 새로운 TriggerBuilder를 생성한다..withIdentity("myTrigger", "group1")
: 트리거에 "myTrigger"라는 고유한 이름과 "group1"이라는 그룹을 할당한다. 이를 통해 트리거를 식별하고 관리할 수 있다..withSchedule(CronScheduleBuilder.cronSchedule("0 0 10 ? * MON"))
CronScheduleBuilder.cronSchedule("0 0 10 ? * MON")
: cron 표현식을 사용하여 트리거의 실행 스케줄을 설정한다."0 0 10 ? * MON"
: cron 표현식으로, 이는 매주 월요일 오전 10시 0분 0초에 트리거가 작동하도록 지정한다..build();
즉, 매주 월요일 오전 10시에 실행되는 CronTrigger이다.
👻 cron 표현식 구성
* * * * *
- - - - -
| | | | |
| | | | +----- 요일 (0 - 6) (0이나 7이 일요일)
| | | +---------- 월 (1 - 12)
| | +--------------- 일 (1 - 31)
| +-------------------- 시 (0 - 23)
+------------------------- 분 (0 - 59)
👻 Cron Expression
* * * * *
: 매 분*/30 * * * *
: 30분마다30 5 * * *
: 매일 오전 5시 30분30 5 * * 1
: 매주 월요일 오전 5시 30분30 5 1 * *
: 매월 1일 오전 5시 30분1단계
: 스케줄러 초기화
2단계
: 작업 스케줄링
3단계
: 작업 실행
4단계
: 작업 완료
5단계
: 스케줄러 종료
데이터베이스 설정을 따로 안하면, 기본으로 인메모리 기반으로 동작한다. 애플리케이션이 재시작하면 휘발성으로 데이터는 사라진다. DB에 저장하기 위해서는 properties 설정을 해야한다. 그리고 Quartz 연동 데이터베이스에 Quartz 관련 테이블을 생성하면 된다.
spring.quartz.job-store-type
: Quartz가 작업(Job)과 트리거(Trigger) 정보를 저장하는 방식을 지정. 기본값은 memory(인메모리) 방식이고 jdbc(데이터베이스에 저장)으로 설정할 수 있다.
spring.quartz.properties.org.quartz.scheduler.instanceName
: Quartz 스케줄러 인스턴스의 이름을 지정한다. 여러 스케줄러 인스턴스를 사용할 때 구분하기 위한 목적으로 사용된다.
spring.quartz.properties.org.quartz.scheduler.instanceId
: Quartz 스케줄러 인스턴스의 ID를 지정한다. AUTO로 설정하면 Quartz가 자동으로 고유 ID를 생성한다.
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!");
}
}
1. Job 생성
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("myJob", "group1")
.build();
JobBuilder.newJob(MyJob.class)
: MyJob 클래스의 인스턴스를 사용하여 새로운 JobDetail 객체를 생성한다..withIdentity("myJob", "group1")
: 작업에 "myJob"이라는 이름과 "group1"이라는 그룹을 지정한다..build()
: 작업 세부 정보를 구축한다.2. Trigger 생성
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10)
.repeatForever())
.build();
TriggerBuilder.newTrigger()
: 새로운 Trigger 객체를 생성한다..withIdentity("myTrigger", "group1")
: 트리거에 "myTrigger"라는 이름과 "group1"이라는 그룹을 지정한다..startNow()
: 트리거를 즉시 시작한다..withSchedule(...)
: 간단한 스케줄을 설정한다. 여기서는 10초 간격으로 무한 반복한다..build()
: 트리거 구성을 완료한다.Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
new StdSchedulerFactory().getScheduler()
: StdSchedulerFactory를 사용하여 새로운 Scheduler 인스턴스를 생성한다.scheduler.start()
: 스케줄러를 시작한다.scheduler.scheduleJob(job, trigger)
: 생성한 작업과 트리거를 스케줄러에 등록한다.즉 이 작업은 10초마다 "Hello Quartz"를 출력하는 Job을 실행하는 예시이다.
Spring Quartz를 활용해서 스케줄링을 구현 해보자.
단순 스케쥴링을 위해서 Quartz를 연동할 필요는 없을 것 같다. 간단한 스케쥴은 @Schedule 어노테이션으로 구현하자.
복잡한 스케줄링 구현이 필요하다면 Quartz를 연동하면 좋을 것 같다.