Quartz JobStore에는
RAM JobStore : Scheduler Data를 메모리에 저장
JDBC JobStore : Scheduler Data를 DB에 저장
가 있다.
오늘은 Scheduler Data를 메모리에 저장하는 RAM JobStore를 Spring Boot로 구현해본다.
소스코드 : github.com/Gupuroom/QuartzRamJobStore.git
개발환경
Eclipse 2020-09 - 필수
SpringBoot - 필수
Gradle - 필수
Lombok - 필수
Quartz - 필수
1. build.gradle에 의존성 추가.
implementation 'org.springframework.boot:spring-boot-starter-quartz'
2. Quartz 관련 설정
Quartz관련 설정은 application.yml과 javaConfig로 할 수 있다. 예시에서는 application.yml을 사용한다.
spring:
quartz:
wait-for-jobs-to-complete-on-shutdown: true
properties:
org:
quartz:
scheduler:
skipUpdateCheck: true
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 5
jobStore:
class: org.quartz.simpl.RAMJobStore
plugin:
shutdownhook:
class: org.quartz.plugins.management.ShutdownHookPlugin
cleanShutdown: true\
3. Job
- Trigger가 발생했을 때 실질적으로 동작할 내용을 정의한다.
- Trigger발생시 스케줄러는 JobExecutionContext 객체를 넘겨주고 execute()를 호출해 Job에 정의되어 있는 내용을 실행시킨다.
- JobExecutionContext는 Scheduler, Trigger, JobDetail등을 포함하여 Job인스턴스에 대한 정보를 저장해논 객체다.
- Spring, SpringBoot에서는 executeInternal()을 사용한다. (Spring에서 execute()인터페이스를 정의해논 QuartzJobBean 객체를 지원하기 때문이다.
CronJob
public class CronJob extends QuartzJobBean {
private int MAX_SLEEP_IN_SECONDS = 5;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String Dev = jobDataMap.getString("Dev");
String Company = jobDataMap.getString("Company");
JobKey jobKey = context.getJobDetail().getKey();
log.info("============================================================================");
log.info("Develope by {} from {}", Dev, Company);
log.info("CronJob started :: sleep : {} jobKey : {}", MAX_SLEEP_IN_SECONDS, jobKey);
IntStream.range(0, 4).forEach(i -> {
log.info("CronJob Counting - {}", i);
try {
TimeUnit.SECONDS.sleep(MAX_SLEEP_IN_SECONDS);
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
});
log.info("CronJob ended :: jobKey : {}", jobKey);
log.info("============================================================================");
}
}
: context에서 jobDataMap 객체를 가져와 log로 호출하는 Job.class이다.
4. JobDetail
- Job을 실행시키기 위한 정보를 담고 있는 객체다.
- Job의 이름, 그룹, JobDataMap 속성 등을 지정할 수 있다.
- Trigger가 Job을 수행할 때 이 정보를 기반으로 스케줄링 한다.
@Bean
public JobDetail scheduleJobDetail()
{
JobDataMap jobMap = new JobDataMap();
jobMap.put("Dev", "이동재");
jobMap.put("Company", "*****");
return JobBuilder
.newJob(CronJob.class).withIdentity("scheduleJob").usingJobData(jobMap).storeDurably()
.build();
// return JobBuilder
// .newJob(CronJob.class).withIdentity("scheduleJob").usingJobData("name","이동재").storeDurably()
// .build();
}
scheduleJobDetail()에서는
- JobBuilder를 통해서 JobDetail을 생성한 후에 반환한다.
- .newJob은 JobDetail을 가진 Trigger가 호출 되었을 때 실행시킬 클래스를 지정해놓은 것이다.
- scheduleJobDetail을 가지고 있는 Trigger가 호출되어 실행되면 3.Job에서 소개한 CronJob이 호출된다.
5. JobDataMap
- JobDataMap은 Job 인스턴스가 실행될 때 사용할 수 있는 정보를 담은 객체다.
- JobDetail을 생성할 때 JobDataMap도 같이 설정한다.
@Bean
public JobDetail scheduleJobDetail()
{
JobDataMap jobMap = new JobDataMap();
jobMap.put("Dev", "이동재");
jobMap.put("Company", "*****");
return JobBuilder
.newJob(CronJob.class).withIdentity("scheduleJob").usingJobData(jobMap).storeDurably()
.build();
// return JobBuilder
// .newJob(CronJob.class).withIdentity("scheduleJob").usingJobData("name","이동재").storeDurably()
// .build();
}
- [주석] JobBuilder.usingJobData를 사용하여 JobDataMap을 설정해 줄 수 있다.
- [“key”,”value”]형식으로 지정하고 Job.class에서 key값으로 value를 가져와 사용한다.
- 여러 개의 Data를 담고 싶을 경우JobDataMap 객체를 만들어서 사용한다.
- JobDataMap에서 설정한 값들은 CronJob.class에서 key값으로 가져올 수 있다. 활용예시는 아래에서 다룬다.
활용 예시
CronJob.java
public class CronJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String Dev = jobDataMap.getString("Dev");
String Company = jobDataMap.getString("Company");
JobKey jobKey = context.getJobDetail().getKey();
log.info("============================================================================");
log.info("Develope by {} from {}", Dev, Company);
log.info("CronJob started :: jobKey : {}", jobKey);
}
}
- [5행] context객체를 통해 JobDataMap을 가져온다.
- [6행,7행] JobDetail에서 설정한 Key값으로 Dev와 Company의 value를 가져와 log로 화면에 출력한다.
- log로 출력해서 제대로 출력되는지 확인한다. ( 혹시 log가 안된다면 System.out.println()으로 확인해도 된다. )
6. Trigger
- Trigger는 Scheduler가 Job을 실행시킬 조건(ex.반복 횟수, 시작시간)등을 설정한다.
- Scheduler는 해당 정보를 기반으로 Job을 수행한다.
scheduleJobTrigger
@Bean
public Trigger scheduleJobTrigger()
{
//cron
CronScheduleBuilder cronBuilder = CronScheduleBuilder.cronSchedule("0/20 * * * * ?");
return TriggerBuilder
.newTrigger().forJob(scheduleJobDetail()).withIdentity("scheduleTrigger").withSchedule(cronBuilder)
.build();
}
- CronScheduleBuilder를 사용해 반복 및 시작 조건을 설정한다.
- TriggerBuilder를 통해 JobDetail과 cronBuilder를 설정한다.
참고
'Spring' 카테고리의 다른 글
[Spring boot] Form 서버 연동 시 에러 발생 해결 (0) | 2021.07.28 |
---|