티스토리 뷰

독자적으로 스케쥴러에 의해 실행되는 Spring Batch Job이 있다. 결과물이 jar로 빌드되어져 나오고 스케쥴러가 그 jar를 실행시켜 우리가 만든 Batch Job이 수행된다. 하지만 이렇게 스케쥴러에 의해 돌아가는 Batch 외에 Web (Online)에서 Batch를 실행시키고 싶다는 요구사항이 있다. 이렇게 요구만 있으면 언제든지 실행시키는 Batch 방식을 On Demand Batch라 한다.

기본적으로 프로젝트를 하면 Online이 있고 Batch가 있다. 그래서 Online은 Online대로 돌고 Batch는 Batch대로 돈다. 그런데 Batch에서 수행하는 일을 Online에서도 원할 때가 있다. Online에도 Batch에서 사용한 Service를 추가해서 사용하면 되는거 아니냐 할수도 있지만 이게 한두건이면 그렇게 할 수 있지만 양이 많다면 그렇게 하기 힘들다. 소스 또한 이중으로 관리가 되어야 하기 때문에 현실적으로 어렵다. 그렇기 때문에 Ondemand 구성 방식은 Batch 프로젝트를 Online 프로젝트에서 참조하는 방식으로 진행을 하겠다.


잘 돌아가는 Batch 프로젝트 A가 있다. 또한 잘 돌아가는 Online 프로젝트 B가 있다고 가정한다. 모든 설정 및 소스코드의 변경은 Online에서만 이루어진다. 표준 Spring Batch를 사용한다면 Batch 프로젝트에서는 변경할것이 없다.

Online pom.xml

<dependencies> 
... 
  <dependency> 
    <groupId>oingdaddy</groupId> 
    <artifactId>oing-batch</artifactId> 
    <version>1.0.0</version> 
  </dependency>

B의 pom.xml 에 다음과 같이 A의 dependency를 추가해 주자.

Online application.yml

spring: 
  batch: 
    job: 
      enabled: false

두번째로 해야 할 일은 Online 프로젝트의 application.yml에 spring.batch.job.enabled=false 설정을 추가하는 것이다. 이 설정을 하지 않으면 Online app이 기동이 될 때 Batch 프로젝트가 모두 실행되는 참사가 일어날 수 있다. 꼭! 해주자. 내가 원하는 Batch job만 수행이 되어야 한다.

Online SampleOndemandController.java

@Controller 
public class SampleOndemandController { 

  @Autowired JobLauncher jobLauncher;

  @Autowired 
  @Qualifier("sampleJob") Job job;
  
  @RequestMapping("/ondemandbatch") 
  @ResponseBody public void handle() throws Exception { 
    JobParameter param = new JobParameter(System.currentTimeMillis()); 
    Map<String,JobParameter> parameters = new HashMap<String,JobParameter>(); 
    parameters.put("requestDate", param); 
    jobLauncher.run(job, new JobParameters(parameters)); 
  } 
}

그다음 해줘야 하는 일은 Online에 위와 같은 Controller를 추가해준다. Batch를 수행할 업무가 있다면 그 Controller에 이 내용을 녹여서 넣어준다. 여기서 핵심은 JobLauncher이다. Spring Batch에서 Job을 실행시켜주는 역할을 하는 이 JobLauncher를 주입받고 또 실행시킬 Job을 주입받는다. 그리고선 JobLauncher로 Job을 실행시켜주면 된다.
위와 같이 param을 넘겨준 이유는 instance 중복 실행을 막기 위해 위와 같이 처리를 했다. 더 좋은 방법이 있다면 바꿔서 써도 된다. 또한 return에 대한 구성은 각자 처리하는 방식대로 처리를 하도록 하자.

이렇게 구성이 끝났으면 Online을 기동시켜보고 /ondemandbatch 로 호출을 해본다. 호출을 했을때 sampleJob이라는 Batch Job이 정상적으로 수행이 되는지 확인을 해본다.

끝!


참고로 Batch 프로젝트의 구성도 간략하게 소개하도록 하겠다. (변경하지 않아도 된다.)

Batch Application.java (springboot main class)

public static void main(String[] args) throws Exception { 
  List<String> params = new ArrayList<>(); 
  for(String key : args){
    params.add(key); 
  } 
  params.add("requestDate="+System.currentTimeMillis()); 
  System.exit(SpringApplication.exit(SpringApplication.run(BatchApplication.class, params.toArray(new String[0])))); 
}

Batch 프로젝트에서도 requestDate 라는 값을 줘서 중복실행이 되지 않게 처리를 해줬다.

Batch sampleJob bean

@Bean 
public Job sampleJob(SampleListener jobListener, Step sampleStep) { 
  return jobBuilderFactory.get("sampleJob") 
           .incrementer(new RunIdIncrementer()) 
           .listener(jobListener) 
           .start(sampleStep) 
           .build(); 
}

Batch 프로젝트에서 sampleJob을 만들어서 돌리고 있던 것을 Online에서 JobLauncher를 통해 실행을 시킨것이라고 보면 된다.

참조 : https://docs.spring.io/spring-batch/docs/current/reference/html/index-single.html#runningJobsFromWebContainer

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31