JAVA Quartz 라이브러리를 이용해 스케줄러 배치 프로그램 개발
시스템에서 스케줄러를 이용한 배치 프로그램은 매우 중요한 역할을 한다. 보통 현장에서 데이터를 Summary하거나 시스템간 데이터를 통합 관리할 때 많이 사용한다.
과거에는 PL/SQL을 이용해 Batch Job을 만들거나 DB Link를 이용해 직접 타 시스템 데이터베이스에 접근하는 방법을 사용했는데 요즘에는 스케줄러 배치 프로그램을 만들어서 사용하는 추세다. 그래서 JAVA로 Quartz 라이브러리를 이용해 간단한 스케줄러 배치 프로그램을 만들어보았다.
👉 Quartz 란?
Java 애플리케이션 내에 통합될 수 있는 다양한 기능을 갖춘 오픈 소스 Job 스케줄링 라이브러리다.
여러 Job들을 실행하기 위한 일정을 만들 수 있다.
👉 Quartz 라이브러리 추가하기
Maven을 이용해 Quartz 라이브러리를 추가하자.
pom.xml 파일 <dependencies> 안에 아래 코드를 추가하자
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
👉 Quartz 구성요소
Job, JobListener, TriggerListener 를 상속하는 클래스들을 생성한다.
1. Job
실제 작업을 수행하는 역할을 한다.
Job 인터페이스를 상속받아 execute 메서드에 로직을 구현한다.
2. JobListener
Job의 시작, 중단, 완료시점을 처리할 수 있는 객체다.
3. TriggerListener
Trigger의 시작, 작업 실행 거부, 실패, 완료시점을 처리할 수 있는 객체다.
4. SchedulerListener
Job과 Trigger에 대한 세부 기능들을 처리할 수 있는 객체다.
(ex: Trigger 멈춤, Job 석제 및 추가 등등)
JobListener, TriggerListener 2개로도 충분히 기능을 구현할 수 있다.
👉 소스 코드
1. MyJobLauncher.java
main 함수를 갖고있는 클래스로 Quartz Scheduler를 실행한다.
public class MyJobLauncher {
public static void main(String[] args) {
try {
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
// Listener 설정
ListenerManager listenrManager = scheduler.getListenerManager();
listenrManager.addJobListener(new MyJobListener());
listenrManager.addTriggerListener(new MyTriggerListener());
listenrManager.addSchedulerListener(new MyScheduleListener());
// Job Executer 설정
Class<? extends Job> jobClass = MyJob.class;
// Job Data 셋업
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("message", "Hello Quartz Scheduler!");
// Job 생성
JobDetail jobDetail = JobBuilder.newJob(jobClass).usingJobData(jobDataMap).build();
// Cron Trigger 생성
// 20초마다 반복(0, 20, 40)
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder
.cronSchedule(new CronExpression("0/20 * * * * ?"));
CronTrigger cronTrigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity("cron", "cron_group")
.withSchedule(cronScheduleBuilder).forJob(jobDetail).build();
// Simple Trigger 생성
// 10초마다 총 6회 반복
SimpleScheduleBuilder simpleSch = SimpleScheduleBuilder.repeatSecondlyForTotalCount(6, 10);
SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity("simple", "simple_group").withSchedule(simpleSch).forJob(jobDetail).build();
// Trigger 설정
Set<Trigger> triggerSet = new HashSet<Trigger>();
triggerSet.add(cronTrigger);
triggerSet.add(simpleTrigger);
// Schedule 등록
scheduler.scheduleJob(jobDetail, triggerSet, false);
scheduler.start();
} catch (Exception e) {
// TODO: handle exception
}
}
}
2. MyJob.java
Job의 기능을 구현하는 클래스다. execute 메서드안에 Job 기능에 맞게 로직을 구현하면 된다.
public class MyJob implements Job {
private SimpleDateFormat simpleDataformat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSSSS");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String currentDate = simpleDataformat.format(new Date());
String triggerKey = context.getTrigger().getKey().toString();
String message = jobDataMap.getString("message");
System.out.println(String.format("[%s][%s] %s", currentDate, triggerKey, message));
}
}
3. MyJobListener.java
JobListener 인터페이스를 상속받아 Job의 시작, 중단, 완료시점에 로직을 구현할 수 있다.
public class MyJobListener implements JobListener {
@Override
public String getName() {
return MyJobListener.class.getName();
}
@Override
public void jobToBeExecuted(JobExecutionContext context) {
System.out.println(
String.format("[%-26s][%s] 작업시작", "jobToBeExecuted", context.getJobDetail().getKey().toString()));
}
@Override
public void jobExecutionVetoed(JobExecutionContext context) {
System.out.println(
String.format("[%-26s][%s] 작업중단", "jobExecutionVetoed", context.getJobDetail().getKey().toString()));
}
@Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
System.out.println(
String.format("[%-26s][%s] 작업완료", "jobWasExecuted", context.getJobDetail().getKey().toString()));
}
}
4. MyTriggerListener.java
TriggerListener 인터페이스를 상속받아 Trigger의 시작, 작업 실행 거부, 실패, 완료시점에 로직을 구현할 수 있다.
public class MyTriggerListener implements TriggerListener {
public static final String EXECUTION_COUNT = "EXECUTION_COUNT";
public String getName() {
return MyTriggerListener.class.getName();
}
@Override
public void triggerFired(Trigger trigger, JobExecutionContext context) {
System.out.println(String.format("[%-26s][%s] Trigger 발사", "triggerFired", trigger.getKey().toString()));
}
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
// 여기가 True 일 경우 수행 안됨
System.out.println(
String.format("[%-26s][%s] Trigger 발사 거부 체크", "vetoJobExecution", trigger.getKey().toString()));
return false;
}
@Override
public void triggerMisfired(Trigger trigger) {
System.out.println(String.format("[%-26s][%s] Trigger 불발", "triggerMisfired", trigger.getKey().toString()));
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext context,
CompletedExecutionInstruction triggerInstructionCode) {
System.out.println(String.format("[%-26s][%s] Trigger 완료", "triggerComplete", trigger.getKey().toString()));
System.out.println("==============================================================================================");
}
}
👉 실행 결과
1개의 Job이 두개의 Trigger를 통해 반복 수행하는 모습을 볼 수 있다.
Quartz 라이브러리를 이용해 간단한 스케줄러 배치 프로그램을 만들어봤다. 여기에 좀 더 응용을 하면 매우 강력한 프로그램이 될 수 있다. 웹 크롤러 프로그램부터 기업의 EAI 시스템 구축까지도 가능하다.
다음 포스팅에는 Quartz 라이브러리의 환경 설정과 좀 더 깊이 있는 기능들을 알아보겠다.
'JAVA' 카테고리의 다른 글
자바(JAVA) 최신 버전으로 개발 환경 세팅하기 이클립스(Eclipse), 그래들(Gradle), JDK 22 (0) | 2024.07.16 |
---|---|
스프링부트(Spring Boot) 시작 배너 로고 숨기기 (0) | 2024.02.22 |
[Java] 자바 이클립스(eclipse)에서 롬복(lombok) 적용 안될 때 오류 해결 방법 (0) | 2024.02.20 |
이클립스(Eclipse) 자바(JAVA) 스프링부트(Spring Boot) 개발 환경 구성하기 (0) | 2024.02.19 |
이클립스 Eclipse 콘솔창 한글 깨짐 해결 방법 (0) | 2023.09.22 |
댓글