Page tree
Skip to end of metadata
Go to start of metadata

6장은 어떻게 스프링 부트를 사용해 스프링 배치 잡을 쉽게 실행하는지 알아본다.

스프링 부트로 잡 시작하기

  • JobLauncherCommandLineRunner 가 JobLauncher를 사용해 잡을 실행한다
  • 스프링 부트가 ApplicationContext 내 구성된 모든 CommandLineRunner를 실행할때 클래스 패스에 spring-boot-starter-batch가 존재하면 JobLauncherCommandLineRunner는 컨텍스트 내 모든 잡을 실행
  • 특정 잡만 실행 가능 spring.batch.job.names 에 명시

REST 방식으로 잡 실행하기

  • SimpleJobLauncher 제공
  • 기본적으로 동기식 TaskExecutor를 사용. 다른 스레드에서 잡을 실행하려면 비동기도 가능
@Autowired
private ApplicationContext context;

@PostMapping("/run")
public ExitStatus run(@RequestBody JobLaunchRequest request) {
	Job job =  this.context.getBean(request.getName(), Job.class);
	return this.jobLauncher.run(job, request.getJobRarameters()).getExitStatus();
}
  • 잡 이름과 잡 파라미터를 요청으로 받아서 잡 런처로 실행
  • JobParmetersIncrementer를 사용해서 파라미터를 증가하시키는 방법을 사용

쿼츠를 사용해 스케줄링 하기

쿼츠 (quartz)

  • 쿼츠는 스케줄러, 잡, 트리거라는 세가지 주요 컴포넌트를 가진다.
  • 스케줄러는 SchedulerFactory를 통해 가져올 수 있고 JobDetails 및 트리거의 저장소 기능을 한다.
  • 스케줄러는 연관된 트리거가 작송할 때 잡을 실행하는 역할은 한다.
  • 잡은 실행할 잡업의 단위다.
  • 트리거는 잡겁 실행 시점을 정의한다
  • 트리거가 작동돼 쿼츠에게 잡을 실행하도록 지시하면 잡의 개별 실행을 정의하는 JobDetail 객체가 생성된다.


public class BatchScheduledJob extends QuartzJobBean {
		// job 등록
}

@Configuration
public class QuartzConfiguration {

	@Bean
	public JobDetail quartzJobDetail() {
		return JobBuilder.newJob(BatchScheduledJob.class) //잡에 쿼츠 등록
				.storeDurably()
				.build();
	}

	@Bean
	public Trigger jobTrigger() {
		SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
				.withIntervalInSeconds(5).withRepeatCount(4); //5초 마다 잡을 기동해 최초 한 번 수행 후 4번 반복 (총 5회)

		return TriggerBuilder.newTrigger()
				.forJob(quartzJobDetail())
				.withSchedule(scheduleBuilder)
				.build();
	}
}



잡 중지하기

프로그래밍적으로 중지하기

  • 중지 트랜지션을 사용

    • Step 에서 ExitStatus.STOPPED; 를 사용 해서 아래와 같이 중지


      return this.jobBuilderFactory.get("transactionJob")
      				.start(importTransactionFileStep())
      				.on("STOPPED").stopAndRestart(importTransactionFileStep())
      				.from(importTransactionFileStep()).on("*").to(applyTransactionsStep())
      				.from(applyTransactionsStep()).next(generateAccountSummaryStep())
      				.end()
      				.build();
      
      
    
    
  • StepExecution을 사용해 중지



    private Transaction process(FieldSet fieldSet) {
    		Transaction result = fieldSet.getTrainsaction();
    
    		if(fieldSet == null) {
    			//비즈니스 로직 e			
    			this.stepExecution.setTerminateOnly();
    		}
    
    		return result;
    	}

오류 처리

잡 실패

  • 잡이 중지되면 현재 청크를 롤백.
  • 성공적으로 완료한 작업까진 커밋가능하고 재시작시 중단된 부분을 찾아낼 수 있다.
  • 스프링 배치는 예외가 발생하면 기본적으로 스텝 및 잡이 실패한 것으로 간주

재시작 제어하기

잡의 재시작 방지하기

  • 다시 실행하면 안되는 잡이라면 첫 시도에 잘 동작하면 좋지만 실패하더라더라도 다시 실행하지 않는다
  • preventRestart()

    @Bean
    public Job transactionJob() {
    		return this.jobBuilderFactory.get("transactionJob")
    				.preventRestart() // 요거
    				.start(importTransactionFileStep())
    				.next(applyTransactionsStep())
    				.next(generateAccountSummaryStep())
    				.build();
    }
    
    


재시작 횟수 제한 구성

  • 특정 횟수만 실행되도록 잡 제어가능 startLimit(2)

    @Bean
    public Job transactionJob() {
    		return this.jobBuilderFactory.get("transactionJob")
    				.startLimit(2) // 요거
    				.start(importTransactionFileStep())
    				.next(applyTransactionsStep())
    				.next(generateAccountSummaryStep())
    				.build();
    }

완료된 스텝 재실행하기

  • allowStartIfComplete


    	@Bean
    	public Step importTransactionFileStep() {
    		return this.stepBuilderFactory.get("importTransactionFileStep")
    				.<Transaction, Transaction>chunk(100)
    				.reader(transactionReader())
    				.writer(transactionWriter(null))
    				.allowStartIfComplete(true) // 요거
    				.listener(transactionReader())
    				.build();
    	}

  • No labels