Spring Quartz Batch

From JCFWiKi

Jump to: navigation, search

그림:check.gif

  • 산출물: SpringFramework + Quartz + SpringBatch 사용하기 (예제)
  • 작성자: 나윤주
  • 최초작성일 : 2008/08/08
  • 최종작성일 : 2008/08/11

Copyright © 2008 Daewoo Information Systems Co., Ltd.

그림:information.gif

  • 이 문서는 Web Service 환경에서 SpringFramework와 Quartz 스케줄러를 사용해 SpringBatch를 실행시키는 방법을 설명한다.

목차

[편집] 환경준비

  • 이 예제는 Web Service 환경에서 Spring Batch를 사용하는 것을 목적으로 하며, 이클립스 기반에서 작성되었다.
  • 주요 기술 구성은 SpringFramework와 Quartz, SpringBatch이다.
  • 환경설정
    • 이클립스를 통해 Dynamic Web Project를 생성한다.
    • 주요 라이브러리는 spring.jar, quartz.jar, spring-batch-core.jar, spring-batch-infrastructure.jar, jta.jar, commons-collections.jar, commons-io.jar, commons-logging.jar, commons-pool.jar, hsqldb.jar 등이 있다. 이 라이브러리들은 아래 예제 코드에 포함되어 있다. (/spring-quartz-batch/web/WEB-INF/lib/)

[편집] SpringFramework에서 Quartz 사용하기

  • Quartz는 Java application과 통합되어 job을 스케줄링하고 관리할 수 있는 Job Scheduling System 이다.
  • SpringFramwork에서는 Quartz와 연계하여 스케줄링 할 수 있는 API를 제공한다.
  • SpringFramwork에서 Quartz를 사용하기 위해 스케줄링 할 Job과 스케줄러의 설정이 필요하다.

[편집] Job Class

  • 수행될 Job은 간단하게 Java Class로 작성된다.
  • spring.jar에 포함된 org.springframework.scheduling.quartz.QuartzJobBean Class를 상속하며 executeInternal() 메소드를 구현해야 한다.
  • executeInternal() 메소드에서 수행될 Job의 내용을 작성한다.
  • 간단한 Log를 찍는 job class는 다음과 같이 구현할 수 있다.
/* HelloJob.java */
package quartz.example;
 
import java.util.Date;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
 
public class HelloJob extends QuartzJobBean {
 
    private static Log _log = LogFactory.getLog(HelloJob.class);
    
    public HelloJob() {
    }
    
    protected void executeInternal(JobExecutionContext context) {
    	_log.info("<<<<<<<< Hello World! - " + new Date() + " >>>>>>>>");
    }
 
}

[편집] Job/Scheduler Configuration

  • Job과 scheduler의 설정은 xml 파일에서 이루어진다.
  • xml 설정 파일은 web.xml에서 contextConfigLocation 설정에 포함시켜 웹 서비스가 시작됨과 동시에 스케줄된 Job이 작동하도록 한다.
  • Job을 실행시키는 스케줄을 담고 있는 Trigger로는 SimpleTriggerBean과 CronTriggerBean이 있다.
    • SimpleTrigger는 한번 발생하는 Job이나 일정한 주기를 가지고 반복되는 Job 등에 적용할 수 있다.
    • CronTrigger는 Calendar 기반 즉, 년/월/일/시/분/초/요일 등을 기준으로 실행되어야 하는 Job 등에 적용할 수 있다.
  • TriggerBean을 통해 작성된 스케줄은 SchedulerFactoryBean에 등록함으로써 작동된다.
  • 아래 코드에서는 simpleTrigger를 사용하여 서비스가 시작되고 10초 후 부터 50초 간격으로 Job을 실행시키도록 스케줄하였다.
<beans ...(xmlns 설정)>
	<bean id="helloJob" class="org.springframework.scheduling.quartz.JobDetailBean">
		<property name="jobClass" value="quartz.example.HelloJob" />
	</bean>
	
	<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail" ref="helloJob" />
		<property name="startDelay" value="10000" />
		<property name="repeatInterval" value="50000" />
	</bean>
	
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="simpleTrigger"/>
			</list>
		</property>
	</bean>
</beans>

[편집] SpringFramework + Quartz + SpringBatch 사용하기

그림:warning.gif

  • Spring Batch는 경우에 따라 다양한 설정이 가능하고, 필요할 수 있으므로 반드시 레퍼런스를 참고하여 사용하도록 한다.
  • 위에서 설명한 SpringFramework + Quartz의 Quartz Job에서 Spring Batch Job을 수행한다.
  • 즉, SpringFramework를 사용하는 웹 서비스에서 Quartz를 통해 스케줄링을 하고, Spring Batch Job을 수행하게 된다.
  • Spring Batch Job을 수행하기 위해 Spring Batch의 JobLauncher, JobRepository 등의 설정과 Job에 대한 정의가 필요하다.

[편집] Job과 연관된 components 설정

  • JobRepository와 JobLauncher는 Job의 실행을 위한 기본적으로 지정해주어야 하는 설정이다.
    • JobRepository는 Job을 관리하는 Repository로 데이터베이스 및 데이터소스 설정을 한다.
    • JobLauncher는 Job과 실행 Parameter를 전달하여 Job의 실행을 도와주는 역할을 한다.
  • SimpleJob과 TaskletStep 등은 미리 정의해 놓고 간단한 Job을 정의할 때 상속받아 사용할 수 있도록 한다.
	<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
		<property name="databaseType" value="hsql" />
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
		<property name="jobRepository" ref="jobRepository" />
	</bean>
	
	<bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
		<property name="jobRepository" ref="jobRepository" />
	</bean>
	
	<bean id="taskletStep" class="org.springframework.batch.core.step.tasklet.TaskletStep" abstract="true">
		<property name="jobRepository" ref="jobRepository" />
	</bean>

[편집] Job의 정의

  • Job은 xml 파일로 정의되며, Job 내부의 Step이 Java Class로 구현된다.
  • 위에서 정의한 SimpleJob을 상속받아 개별 Job에 대한 속성을 지정해 줄 수 있다.
  • 여기서는 myHelloJob을 정의하고 내부 Step으로 메시지를 전달하는 Class를 구현하였다.
	<bean id="myHelloJob" parent="simpleJob">
		<property name="name" value="myHelloJob" />
		<property name="steps">
			<list>
				<bean id="firstHello" parent="taskletStep">
					<property name="tasklet">
						<bean class="quartz.example.MyHello">
							<property name="message" value="Hi~" />
						</bean>
					</property>
				</bean>
				<bean id="secondHello" parent="taskletStep">
					<property name="tasklet">
						<bean class="quartz.example.MyHello">
							<property name="message" value="Oh~ Hi~" />
						</bean>
					</property>
				</bean>
			</list>
		</property>
	</bean>
  • 정의한 Job을 Quartz Job에 연결하기 위해, Quartz Job의 정의 및 구현도 변경되어야 한다.
  • 구현한 Quartz Job Class에 SpringBatch의 Job과 JobLauncher 변수를 등록하고 정의에도 추가해 준다.
	<bean id="helloJob" class="org.springframework.scheduling.quartz.JobDetailBean">
		<property name="jobClass" value="quartz.example.HelloJob" />
		<property name="jobDataAsMap">
			<map>
				<entry key="launcher" value-ref="jobLauncher"/>
				<entry key="job" value-ref="myHelloJob"/>
			</map>
		</property>
	</bean>
  • SpringBatch Job은 JobLauncher의 run() API를 통해 실행 시킬 수 있다.
  • Job의 내용이 같을 경우 한번 실행된 Job이므로 이미 완료되었다는 예외가 발생하므로, JobParameter를 다르게 줌으로써 계속적으로 실행 할 수 있도록 한다.
    • 이 예제에서는 JobParameter로 Date를 전달하였다.
/* HelloJob.java */
/* .. 중간생략 .. */
public class HelloJob extends QuartzJobBean {  
	private JobLauncher launcher;
	private Job job;
    
	/* .. 중간생략 .. */
    
	protected void executeInternal(JobExecutionContext context) {
    		_log.info("<<<<<<<< " +  " Hello World! - " + new Date() + " >>>>>>>>");
    	
    		JobParametersBuilder jobParameterBulider = new JobParametersBuilder();
    		jobParameterBulider.addDate("date", new Date());
    	
    		try {
			JobExecution jobExecution = launcher.run(job, jobParameterBulider.toJobParameters());		
		} catch (JobExecutionAlreadyRunningException e) {
			/* .. 중간생략 .. */
		}
	}
 
}

[편집] SpringFramework + Quartz + SpringBatch 예제 다운로드

  • SpringFramework + Quartz + SpringBatch 예제 다운로드
  • 데이터베이스는 hsqldb를 사용하였다.
    • 이 예제에서는 데이터베이스를 사용하지 않으나, 데이터베이스를 사용하는 batch job을 개발할 경우 데이터베이스 설정을 참조할 수 있다.

그림:information.gif

  • 예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. (개인 개발환경 참고)
  • (보충)아래 예제는 Web Service Application인 블로그와 Spring Batch를 적용한 예제이다.
    • Spring MVC 파일 업로드로 저장된 파일을 BLOB 타입으로 변환해서 데이터베이스에 업데이트하는 부분을 배치처리하였다.
    • Spring MVC + SpringFramework + iBatis + HSQL + Quartz + SpringBatch의 조합.
    • 블로그 + Spring Batch 예제 다운로드

[편집] 참고자료