본문 바로가기
Java

[Spring Batch] #2 스프링 배치 Job의 실행 방법

by Jayson Jeong 2022. 9. 20.

이번 포스팅에선 스프링 배치 또는 스프링 배치의 Job을 실행하는 다양한 방법들을 소개하겠다.

 

직전 게시물에서 설명했듯이 스프링 배치는 오직 배치 작업만 수행하고 원하는 시간 또는 특정 조건에서 실행하는 등의 스케줄링 기능은 별도의 오픈소스 스케줄러인 쿼츠(Quartz)나 다른 엔터프라이즈 스케쥴러, 또는 Ci Tool(대표적으로 jenkins가 있다), web 등을 이용해 스프링 배치를 실행하게 된다. 또한 스프링 배치의 모든 Job을 실행할지, 특정 Job만 실행할지 등 많은 고려사항들이 존재하는데 오늘은 몇 가지의 스프링 배치의 실행 방법을 설명하겠다.

 

1. Java Application 실행

스프링 배치의 기능만을 수행하기 위한 별도의 스프링 배치 프로젝트로 구성되어 있고 Spring boot + Spring batch 구성인 경우 적용이 가능하며 필자가 생각하는 가장 간단한 실행 방법이다.

 

일반적인 자바 프로젝트 실행방법과 동일하다. main 클래스를 생성 후 해당 메인 클래스의 실행을 통해 SpringApplication을 실행해주면 된다.

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class BatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(BatchApplication.class, args);
    }
}

 

또한 Argument를 통해 내가 실행하고자 하는 특정 Job만 실행이 가능하다. 아래 소스코드처럼 Argument로 전달받은 jobName과 일치하는 Job일 때 실행하는 내용이 구현되어 있는 것을 볼 수 있다.

JobLauncherApplicationRunner.java

그래서 실행 시 job.name=[Job이름] Argument를 추가해 줄 경우 원하는 특정 Job만 실행이 가능하다.

IDE에서 실행할 때도 동일하다. 

 

리눅스 실행 명령어

java -jar jar명 --job.name=실행할 Job명;

스프링 배치의 모든 Job 실행
$JAVA_HOME/bin/java -jar jbgorund.jar;

스프링 배치의 특정 Job 실행
$JAVA_HOME/bin/java -jar jbgorund.jar --job.name=archive;

 

특정 Job만 실행하도록 설정한 경우 job.name argument가 없을 때 모든 Job을 실행하지 않게 job.name 의 디폴트 값을 적용할 수도 있다. application.properties에 아래와 같이 적용하면 된다.

spring.batch.job.names=${job.name:NONE}

 

2. CommandLineRunner 실행

Spring batch 2.3.0 부터 2.6.0 전 까지는 JobLauncherCommondLineRunner 를 통해 실행이 가능하였으나 2.6.0 이후부터 배치 실행은 JobLauncherApplicationRunner로 통합되었다.

 

다만 spring boot를 실행한 명령에 따라 실행을 달리할 수 있다.

SpringApplication.java

 

JobLauncherApplicationRunner.java

오래된 프로젝트일 경우 엔터프라이즈 스케줄러 등을 스케줄러로 이용하고 있을 경우 이미 구성되어있는 스케줄링 프로그램의 실행이 쉘 스크립트를 이용하거나 커맨드 명령을 이용한 스케줄링으로 구성되어 있을 경우가 많다.

이에 대응하기 위해 CommandLineJobRunner를 이용하여 설정이 가능하다.

CommandLineJobRunner는 main 메소드를 갖고 있기 때문에 CommandLineJobRunner를 main 클래스로 지정 후 아규먼트와 함께 실행시켜 줄 수 있다.

메인 메소드가 별도로 생성한 클래스가 아닌 스프링 배치에서 제공하는 CommondLineJobRunner로 적용하면 된다. 

CommandLineJobRunner.java

-build.gradle의 메인클래스를 CommandLineJobRunner로 적용하고 빌드를 한다.

gradle(kotlin)일 경우 build.gradle.kts에 해당 내용 추가

springBoot{
    mainClass.value("org.springframework.batch.core.launch.support.CommandLineJobRunner")
}


gradle(groovy)일 경우 build.gradle에 해당 내용 추가
jar {
        duplicatesStrategy = DuplicatesStrategy.INCLUDE
        manifest {
            attributes 'org.springframework.batch.core.launch.support.CommandLineJobRunner'
        }
        from {
            configurations.compileClasspath.collect {
                it.isDirectory() ? it : zipTree(it)
            }
        }
  	}

 

 

 

 

이제 커맨드라인으로 스프링 배치를 실행하기 위해 Job설정과 실행할 Job이름을 적용해주어야 하는데

Job bean 생성은 Java 어노테이션을 이용한 bean 생성 방식과 xml을 이용한 bean 생성 방식 모두 적용이 가능하다.

필자는 어노테이션을 이용한 생성방식으로 이미 작성되어있는 ConfigClass를 이용하였다.

 

실행할 Job을 결정할 때 jobName 또는 beanName 으로 검색을 하기 때문에 jobName과 beanName을 일치시켜 주는게 좋다.

 

 

아래와 같은 명령을 통해 Job을 실행할 수 있다.

java -jar [jar파일] [배치config파일] [jobName or job객체의 beanName] [jobParameters]

$JAVA_HOME/bin/java -jar jbgorund.jar com.jbground.batch.job.PartitioningJobConfiguration partitioningJob --job.name=archive;

 

Spring boot 실행 시 자동으로 배치가 실행되는 옵션인 spring.batch.job.enabled 옵션을 꺼 놓지 않을 경우 실행 시 자동 시작으로 인해 Job이 두 번 실행되는 경우가 발생하기 때문에 옵션을 꺼놓도록 한다. 

- application.properties

spring.batch.job.enabled=false

 

 

3. Web or Trigger를 통해 실행하기

JobLauncher와 실행할 Job 객체를 가져와서 실행한다.

@Controller
public class JbgroundController { 

    @Autowired JobLauncher jobLauncher;

    @Autowired
    @Qualifier("jbgroundJob") Job job;

    @RequestMapping("/batch/execute")
    @ResponseBody public void execute() throws Exception { 
        JobParameter param = new JobParameter(System.currentTimeMillis()); 
        Map<String,JobParameter> parameters = new HashMap<String,JobParameter>(); 
        jobLauncher.run(job, new JobParameters(parameters)); 
    }
}