안녕하세요. J4J입니다.
이번 포스팅은 SpringBatch 사용하기 마지막인 Quartz로 클러스터링 처리하는 방법에 대해 적어보는 시간을 가져보려고 합니다.
이전 글
[SpringBoot] SpringBatch 사용하기 (1) - Scheduler를 이용하여 Tasklet, Chunk 배치 만들기
[SpringBoot] SpringBatch 사용하기 (2) - Job Parameter 활용 및 동일 Job 반복 실행
[SpringBoot] SpringBatch 사용하기 (3) - Quartz로 배치 만들기
클러스터링 적용 방법
이전 글을 통해서도 Quartz를 사용해 볼 수 있었지만 Quartz를 적용했다고 해서 모두 클러스터링이 적용된 것은 아닙니다.
클러스터링을 적용하기 위해서는 SpringBatch를 사용할 때 했던 것처럼 메타데이터를 위한 테이블이 생성되어야 하며 부가적인 설정 값들도 필요합니다.
전반적인 설정 과정을 다음과 같이 진행해볼 수 있습니다.
참고로 설정을 하기에 앞서 이전 글에서 적용했었던 것처럼 소스를 작성하면 다음과 같은 이슈를 마주할 수 있습니다.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'start' defined in class path resource [com/quartz/config/LogRegisterScheduleConfig.class]: Failed to instantiate [void]: Factory method 'start' threw exception with message: Couldn't store job: Unable to serialize JobDataMap for insertion into database because the value of property 'applicationContext' is not serializable: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:659) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:493) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.11.jar:6.0.11]
...
해당 소스의 원인은 Job에서 DI를 활용하기 위해서 JobDataMap에 applicationContext의 값을 저장하여 Job에 전달하고 있었는데 Quartz 관련 메타데이터 테이블에 관련 내용들을 적재하면서 직렬화와 관련된 문제를 마주한 것입니다.
말 그대로 JobDataMap에 applicationContext의 값을 담을 수 없었고, 그에 따라 전반적인 소스를 수정할 수밖에 없었습니다.
해당 내용을 참고하며 이전 글을 기반으로 하여 다음 순서대로 설정해보겠습니다.
[ 1. 메타데이터 스키마 생성 ]
인텔리제이를 통해 개발을 하고 계시다면 "Shift + Shift"를 누른 뒤 "tables_mysql_innodb.sql"를 입력하면 다음과 같이 파일 하나가 조회되는 것을 볼 수 있습니다.
해당 파일에는 다음과 같이 메타데이터 스키마 쿼리들이 담겨있고 해당 쿼리들은 사용하고 계시는 데이터베이스에 똑같이 실행시켜 테이블들을 생성해 주시면 됩니다.
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
# I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(190) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(190) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(190) NULL,
JOB_GROUP VARCHAR(190) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
commit;
[ 2. application.properties 설정 ]
# quartz job 유형
spring.quartz.job-store-type=jdbc
# 초기 메타데이터 스키마 구성
spring.quartz.jdbc.initialize-schema=never
[ 3. quartz.properties 설정 ]
해당 파일은 기존에 없는 파일이니 application.properties와 동일 depth인 "/java/resources" 아래에 생성해 주시면 됩니다.
그리고 다음과 같이 입력해 주시면 되고 더 많은 설정 값들은 Quartz 공식 문서에서 확인해주시면 됩니다.
# 유니크한 스케줄러 작업을 위한 ID 설정
org.quartz.scheduler.instanceId=AUTO
# quartz 메타데이터가 사용될 dataSource 설정
org.quartz.dataSource.quartzDataSource.URL=jdbc:사용하는 DB URL
org.quartz.dataSource.quartzDataSource.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.quartzDataSource.user=사용하는 DB 계정
org.quartz.dataSource.quartzDataSource.password=사용하는 DB 비밀번호
org.quartz.dataSource.quartzDataSource.provider=hikaricp
# quartz dataSource를 위에서 설정한 이름으로 설정
org.quartz.jobStore.dataSource=quartzDataSource
# jobStroe 설정
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=false
# quartz 메타디엍 테이블 명 prefix (default QRTZ_)
org.quartz.jobStore.tablePrefix=QRTZ_
# 잘못된 실행에 대한 트리거 허용 시간 (default 60000)
org.quartz.jobStore.misfireThreshold=60000
# 인스턴스 간 검사하는 빈도 (default 15000)
org.quartz.jobStore.clusterCheckinInterval=15000
# 클러스터링 처리 기능 설정 (default false)
org.quartz.jobStore.isClustered=true
# threadPool 설정
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# Thread 갯수 설정 (1 ~ 100) (default -1) (실행되는 Job이 적으면 1이어도 상관 없지만 매분 많은 Job들이 실행되면 50, 100까지 높여야 함)
org.quartz.threadPool.threadCount=10
# Thread 우선순위 설정 (1 ~ 10) (default 5)
org.quartz.threadPool.threadPriority=5
[ 4. Autowired Job Factory 클래스 생성 ]
이번에 생성하는 Job Factory는 Job에서 Autowired 처리가 가능하도록 도와주는 클래스입니다.
다음과 같이 구성하시면 됩니다.
package com.quartz.jobfactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
[ 5. Job 클래스 변경 ]
이전 글에서 Job 클래스를 미리 생성해 둔 것이 있습니다.
동일한 기능을 수행하도록 다음과 같이 변경해 보겠습니다.
package com.quartz.job;
import com.quartz.entity.LogEntity;
import com.quartz.repository.LogJpaRepository;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class LogRegisterJob implements Job {
@Autowired
private LogJpaRepository logJpaRepository; // requiredArgsConstructor 사용 불가
/**
* Job에서 실행될 작업을 정의한다.
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 로그 데이터 적재
logJpaRepository.save(
LogEntity
.builder()
.contents("logRegisterJobContents")
.createAt(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.updateAt(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.build()
);
}
}
[ 6. Schedule Config 클래스 변경 ]
Job 클래스와 마찬가지로 이전 글에서 Schedule Config를 위한 클래스를 미리 생성해 둔 것이 있습니다.
기존에는 StdSchedulerFactory를 활용했지만 클러스터링 설정을 하면서 SchedulerFactoryBean으로 변경하여 사용해야 적용이 가능했습니다.
그래서 이전과 동일한 기능을 수행하도록 다음과 같이 변경해 보겠습니다.
package com.quartz.config;
import com.quartz.job.LogRegisterJob;
import com.quartz.jobfactory.AutowiringSpringBeanJobFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Trigger;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
import java.io.IOException;
import java.util.Properties;
@Configuration
@RequiredArgsConstructor
@Slf4j
public class LogRegisterScheduleConfig {
private final ApplicationContext applicationContext;
/**
* 스케줄링 설정
*
* @return 스케줄러 Bean
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
// schedulerFactoryBean으로 변경하여 설정
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
// @Autowired 사용을 위한 설정
AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory = new AutowiringSpringBeanJobFactory();
autowiringSpringBeanJobFactory.setApplicationContext(applicationContext);
schedulerFactoryBean.setJobFactory(autowiringSpringBeanJobFactory);
// quartz scheduling 관련 설정
schedulerFactoryBean.setQuartzProperties(properties());
// 스케줄링을 위한 Trigger 등록
schedulerFactoryBean.setTriggers(new Trigger[]{simpleTriggerFactoryBean().getObject()});
return schedulerFactoryBean;
}
/**
* JobDetail 설정
*
* @return JobDetail Bean
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
// 실행될 Job
jobDetailFactoryBean.setJobClass(LogRegisterJob.class);
// 식별을 위한 Identity 등록 (group)
jobDetailFactoryBean.setGroup("LogRegisterJobDetailGroup");
// 식별을 위한 Identity 등록 (name)
jobDetailFactoryBean.setName("LogRegisterJobDetailName");
return jobDetailFactoryBean;
}
/**
* Trigger 설정
*
* @return Trigger Bean
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();
simpleTriggerFactoryBean.setJobDetail(jobDetailFactoryBean().getObject());
// 5초 간격으로 스케줄링 처리
simpleTriggerFactoryBean.setRepeatInterval(5000);
// 식별을 위한 Identity 등록 (group)
simpleTriggerFactoryBean.setGroup("LogRegisterTriggerGroup");
// 식별을 위한 Identity 등록 (name)
simpleTriggerFactoryBean.setName("LogRegisterTriggerName");
return simpleTriggerFactoryBean;
}
/**
* 스케줄링 Properties 설정
*
* @return Properties
*/
@Bean
public Properties properties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
// quartz.properties 연결하기
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
log.info("quartzProperties set error");
}
return properties;
}
}
이상으로 SpringBatch 사용하기 네 번째인 Quartz로 클러스터링 처리하는 방법에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Spring > SpringBoot' 카테고리의 다른 글
[SpringBoot] i18n을 활용하여 다국어 처리하기 (0) | 2023.09.18 |
---|---|
[Springboot] Jacoco를 이용하여 테스트 커버리지 확인하기 (1) | 2023.09.16 |
[SpringBoot] SpringBatch 사용하기 (3) - Quartz로 배치 만들기 (0) | 2023.09.03 |
[SpringBoot] SpringBatch 사용하기 (2) - Job Parameter 활용 및 동일 Job 반복 실행 (0) | 2023.08.26 |
[SpringBoot] SpringBatch 사용하기 (1) - Scheduler를 이용하여 Tasklet, Chunk 배치 만들기 (0) | 2023.08.22 |
댓글