Quartz는 자바 기반의 오픈 소스 스케줄링 라이브러리다.
완전히 자바로 개발되어 어느 자바 프로그램에서도 쉽게 통합해서 개발할 수 있으며, 수천 개의 작업도 실행 가능하며 간단한 interval 형식이나 Cron 표현식으로 복잡한 스케줄링도 지원한다.
스케줄러 간의 Clustering기능을 제공하여 대규모 시스템에서도 유연하게 활용될 수 있다.
Job 실행과 Trigger 스케줄링을 관리하는 인터페이스
Scheduler는 SchedulerFactory에 의해서 생성된 후 shutdown() 메서드에 의해서 없어질 때까지 실행된다.
Scheduler가 생성되면 Job과 Trigger를 추가하거나 삭제 또는 그 리스트를 가져 오거나 트리거를 일시 멈추는 것과 같은 일정과 관련된 조작을 할 수 있다.
start() 메서드에 의해서 시작되기 전까지 Job을 실행시키는 Trigger는 전혀 작동되지 않는다.
실행할 작업에 대한 정보를 포함하는 클래스
Quartz API에서 단 하나의 메서드를 가진 execute(JobExecutionContext context) Job 인터페이스를 제공한다.
개발자는 구현부를 이 메서드에서 구현하면 된다.
Job의 Trigger가 발생하면 스케줄러는 JobExecutionContext 객체를 넘겨주고 execute 메서드를 호출한다.
JobExecutionContext는 Scheduler, Trigger, JobDetail 등을 포함하여 Job 인스턴스에 대한 정보를 제공하는 객체이다.
public interface Job {
public void execute(JobExecutionContext context) throws JobExecutionException;
}
public abstract class QuartzJobBean implements Job {
@Override
public final void execute(JobExecutionContext context) throws JobExecutionException {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValues(context.getScheduler().getContext());
pvs.addPropertyValues(context.getMergedJobDataMap());
bw.setPropertyValues(pvs, true);
}
catch (SchedulerException ex) {
throw new JobExecutionException(ex);
}
executeInternal(context);
}
protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;
}
Job에 지정된 Trigger가 작동하면 스케줄러에 의해 execute() 메서드가 호출된다.
JobExecutionContext객체가 런타임 환경에 대한 정보를 제공하고 정보에는 Job을 실행시킨 Scheduler의 핸들, 작동된 Trigger의 핸들, Job의 JobDetail 객체 등의 정보가 포함되어 있다.
Job을 실행시키기 위한 정보를 담고 있는 객체
Job의 이름, 그룹, JobDataMap 속성 등을 지정할 수 있다. Trigger가 Job을 수행할 때 이 정보를 기반으로 스케줄링을 한다.
/**
* Job 생성
* @param quartzDto - Quartz Job 정보
* @param jobClass - Job 생성할 Class
* @param context - ApplicationContext
* @return JobDetail
*/
public static JobDetail createJob(QuartzDto quartzDto, Class<? extends Job> jobClass, ApplicationContext context) {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(jobClass);
factoryBean.setDurability(false);
factoryBean.setApplicationContext(context);
factoryBean.setName(quartzDto.getJobName());
factoryBean.setGroup(quartzDto.getJobGroup());
factoryBean.setDescription(quartzDto.getDesc());
if (quartzDto.getJobDataMap() != null) {
factoryBean.setJobDataMap(quartzDto.getJobDataMap());
}
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
Job을 실행시킬 스케줄링 조건 (ex. 반복 횟수, 시작시간) 등을 담고 있고 Scheduler는 이 정보를 기반으로 Job을 수행시킨다.
Quartz는 SimpleTrigger와 CronTrigger를 제공한다.
SimpleTrigger
한 번만 실행되는 작업을 다루거나 특정 시간에 시작해서 일정한 반복주기로 실행되는 작업을 정의하는 데 사용
CronTrigger
Cron표현식이 사용됩니다. Cron표현식은 일정을 설명하는 7개 부분으로 된 표현식으로 구성되어 있습니다.
EX)
“0 0/5 * * * ?” : 5분마다 작동
“10 0/5 * * * ?” : 매 시간 0분 10초에 시작해서 5분마다 작동 (10:00:10 am, 10:05:10 am)
“0 30 10-13 ? * WED,FRI” : 매주 수요일, 금요일, 10:30, 11:30, 12:30, 13:30 작동
“0 0/30 8-9 5,20 * ?” : 매월 5일과 20일, 8시와 9시, 0분과 30분에 작동 (8:00, 8:30, 9:00, 9:30)
Trigger 속성
Listener는 Scheduler의 이벤트를 받을 수 있도록 Quartz에서 제공하는 인터페이스이며 2가지를 제공한다.
Job과 Trigger의 정보를 저장하는 방식을 정의한다.
RAM, JDBC, Redis JobStore 등이 있지만 우리가 주의 깊게 봐야 할 것은 JDBC JobStore다.
스케줄 정보를 DB에 저장하고, 시스템이 셧다운 되더라도 스케줄 정보는 유지되기 때문에 재시작 시 다시 Job을 실행할 수 있다.
Clustering 기능을 사용할 수 있다.
Sample 코드를 작성하면서 Quartz의 동작과 아키텍처 구조를 이해해 보자.
[JAVA] Quartz - Spring boot Example (42) | 2024.08.03 |
---|
댓글 영역