본문 바로가기
Spring/SpringBoot

[SpringBoot] SpringBatch 사용하기 (4) - Quartz로 클러스터링 처리하기

by J4J 2023. 9. 10.
300x250
반응형

안녕하세요. 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

 

quartz.properties 위치

 

 

 

[ 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로 클러스터링 처리하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글