Spring Boot 일괄 재시작 작업 예제

https://loizenai.com/spring-boot-batch-restart-job/
  • 자습서: "SpringBoot RestAPI 구현을 사용한 Spring Boot 배치 다시 시작 작업 예"

  • SpringBatch는 Job과 함께 재시작 가능한 메커니즘을 제공합니다. 그래서 튜토리얼에서 SpringBoot로 이 기능의 원리를 제시할 것입니다.

    기술:

    – 자바 1.8
    – 메이븐
    – 스프링 부트
    – 스프링 도구 세트

    개요 - Spring Boot Batch 재시작 작업 예제



    Reader & Writer로 간단한 단계가 있는 배치 작업을 생성합니다.
  • 판독기가 파일 경로 목록을 읽은 다음 기록기로 전달합니다. 쓰기는 파일 경로를 사용하여 각 파일의 내용을 처리합니다.
    배치 작업을 생성한 다음 FileNotFound 오류를 기반으로 다시 시작 가능한 기능을 테스트합니다.

  • 참고: 다시 시작할 수 있는 기본값으로 배치 작업이 생성됩니다. Spring Batch는 재시작 가능 기능을 방지하기 위한 구성도 지원합니다.

    프로젝트 구조 - Spring Boot 일괄 재시작 작업 예제



    [caption id="attachment_4892"align="alignnone"width="687"] Spring Boot Springbatch 재시작 가능 프로젝트 구조[/caption]
  • 수행할 단계:
  • SpringBoot 프로젝트 생성
  • 간단한 단계 만들기
  • 배치 작업 구성
  • Job Launch 컨트롤러 생성
  • 배치 작업 데이터베이스 구성
  • 배치 작업 활성화

  • 시나리오 테스트

    SpringBoot 프로젝트 생성



    Spring Tool Suite를 열고 메인 메뉴에서 File->New->Spring Starter Project를 선택하고 프로젝트 정보를 입력합니다. Next를 누르고 Finish를 누르면 Spring Boot 프로젝트가 성공적으로 생성됩니다.
  • 파일 열기pom.xml, Web MVC, PostgreSQL 및 Spring Batch 종속성 추가:
  • 
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>
    
    <!-- http://mvnrepository.com/artifact/postgresql/postgresql -->
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901-1.jdbc4</version>
    </dependency>
    

    일괄 작업 단계에 대한 판독기 및 작성기 만들기 - Spring Boot 일괄 다시 시작 작업 예제 리더 클래스를 만듭니다. 패키지 com.loizenai.springbatch.step; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.NonTransientResourceException; import org.springframework.batch.item.ParseException; import org.springframework.batch.item.UnexpectedInputException; 공개 클래스 Reader는 ItemReader를 구현합니다.{ 비공개 String[] 파일 = {"C:\\readfile\\1.txt"}; 공개 정적 정수 개수=0; 로거 로거 = LoggerFactory.getLogger(this.getClass()); @우세하다 공개 문자열 읽기()는 예외, UnexpectedInputException, ParseException, NonTransientResourceException {를 throw합니다. if(개수 < 파일 길이){ 반환 파일[count++]; }또 다른{ 카운트=0; } null을 반환합니다. } } 작성기 클래스를 만듭니다. 패키지 com.loizenai.springbatch.step; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.item.ItemWriter; 공개 클래스 Writer는 ItemWriter를 구현합니다. { 로거 로거 = LoggerFactory.getLogger(this.getClass()); @우세하다 public void write(List extends String> paths) 예외 { for(문자열 파일 경로 : 경로){ System.out.println("파일경로 = " + 파일경로); 시도 (스트림 스트림 = Files.lines(Paths.get(filePath))) { stream.forEach(System.out::println); } 잡기(IOException e) { 독자수 = 0; 던지기(e); } } } }

    Spring Boot 배치 작업 구성



    단순 배치 작업 구성:
    
    package com.loizenai.springbatch.config;
     
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.launch.support.RunIdIncrementer;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.loizenai.springbatch.step.Reader;
    import com.loizenai.springbatch.step.Writer;
     
    @Configuration
    public class BatchConfig {
     
        @Autowired
        public JobBuilderFactory jobBuilderFactory;
     
        @Autowired
        public StepBuilderFactory stepBuilderFactory;
     
         
        @Bean
        public Job job() {
            return jobBuilderFactory.get("job")
                    .incrementer(new RunIdIncrementer())
                    .flow(step1())
                    .end()
                    .build();
        }
     
        @Bean
        public Step step1() {
            return stepBuilderFactory.get("step1")
                    . chunk(1)
                    .reader(new Reader())
                    .writer(new Writer())
                    .build();
        }
    
    }

    Spring Boot Batch Job Launch Controller 생성


  • 작업 시작을 위한 간단한 컨트롤러 만들기:
  • 
    package com.loizenai.springbatch.controller;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobExecution;
    import org.springframework.batch.core.JobParameters;
    import org.springframework.batch.core.launch.JobLauncher;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
     
    @RestController
    public class JobLauncherController {
     
        @Autowired
        JobLauncher jobLauncher;
     
        @Autowired
        Job job;
     
        @RequestMapping("/launchjob")
        public String handle() throws Exception {
     
            Logger logger = LoggerFactory.getLogger(this.getClass());
            JobExecution jobExecution = null;
            try {
                jobExecution = jobLauncher.run(job, new JobParameters());
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
     
            return "jobExecution's info: Id = " + jobExecution.getId() + " ,status = " + jobExecution.getExitStatus();
        }
    }

    Spring Boot 배치 작업 데이터베이스 구성



    Spring Batch에 대한 구성 데이터베이스 정보:
    code class="language-java">
    spring.datasource.url=jdbc:postgresql://localhost/testdb
    spring.datasource.username=postgres
    spring.datasource.password=123
    spring.batch.job.enabled=false
    

    스프링 부트 배치 작업 활성화

    In main class of Spring Boot project, use @EnableBatchProcessing to enable Spring Batch.

    
    package com.loizenai.springbatch;
    
    import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @EnableBatchProcessing
    public class SpringBatchRestartableFunctionApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBatchRestartableFunctionApplication.class, args);
        }
    }

    시나리오 테스트 - Spring Boot Batch 재시작 가능 기능


  • Spring Boot 배치 작업을 빌드 및 실행합니다.

  • Reader는 파일 이름C:\readfile\1.txt을 Writer로 전달합니다. 파일을 삭제C:\readfile\1.txt한 다음 시작 요청을 생성합니다. http://localhost:8080/launchjob
    비어 있는 매개변수로 작업 인스턴스가 생성됩니다.
    
    Job: [FlowJob: [name=job]] launched with the following parameters: [{}]
    

    서버 로그 조사:

    결과 실패:
    
    Job: [FlowJob: [name=job]] completed with the following parameters: [{}] and the following status: [FAILED]
    

    원인:
    
    2017-01-13 20:21:29.216  INFO 11012 --- [nio-8080-exec-1] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
    filePath = C:\readfile\1.txt
    2017-01-13 20:21:39.781 ERROR 11012 --- [nio-8080-exec-1] o.s.batch.core.step.AbstractStep         : Encountered an error executing step step1 in job job
    
    java.nio.file.NoSuchFileException: C:\readfile\1.txt
        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) ~[na:1.8.0_101]
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) ~[na:1.8.0_101]
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) ~[na:1.8.0_101]
        at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230) ~[na:1.8.0_101]
    
  • 이제 다음 내용으로 C:\readfile\1.txt를 만듭니다.
  • 
    line1
    line2
    line3
    line4
    line5

    그런 다음 Job Instance(매개변수: [{}] 사용)를 http://localhost:8080/launchjob로 다시 시작합니다.

    결과: COMPLETED
    
    Job: [FlowJob: [name=job]] completed with the following parameters: [{}] and the following status: [COMPLETED]
    
    
    filePath = C:\readfile\1.txt
    line1
    line2
    line3
    line4
    line5
    

    실행 요청을 다시 수행하십시오: http://localhost:8080/launchjob , 결과:
    
    Step already complete or not restartable, so no action to execute: StepExecution: id=1000, version=4, name=step1, status=COMPLETED, exitStatus=COMPLETED, readCount=1, filterCount=0, writeCount=1 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=2, rollbackCount=0, exitDescription=
    Job: [FlowJob: [name=job]] completed with the following parameters: [{}] and the following status: [COMPLETED]
    

    재시작 가능 방지



    SpringBatch는 또한 Job 인스턴스가 FAIL 상태로 실행되는 경우에도 Job의 재시작 가능 기능을 방지하는 구성을 지원합니다.

    구성하는 방법? 약간의 코드 .preventRestart()를 사용하고 BatchConfig 클래스의 세부 사항을 사용하십시오.
    
    package com.loizenai.springbatch.config;
     
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.launch.support.RunIdIncrementer;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.loizenai.springbatch.step.Reader;
    import com.loizenai.springbatch.step.Writer;
     
    @Configuration
    public class BatchConfig {
     
        @Autowired
        public JobBuilderFactory jobBuilderFactory;
     
        @Autowired
        public StepBuilderFactory stepBuilderFactory;
     
         
        @Bean
        public Job job() {
            return jobBuilderFactory.get("job")
                    .preventRestart()
                    .incrementer(new RunIdIncrementer())
                    .flow(step1())
                    .end()
                    .build();
        }
     
        @Bean
        public Step step1() {
            return stepBuilderFactory.get("step1")
                    . chunk(1)
                    .reader(new Reader())
                    .writer(new Writer())
                    .build();
        }
    
    }
    

    Spring Boot 프로젝트를 다시 빌드 및 실행하고 C:\readfile\1.txt 파일을 삭제합니다.

    요청하기: http://localhost:8080/launchjob , -> 결과: 실패(로그 세부 정보 포함):
    
    2017-01-13 20:35:08.664  INFO 5092 --- [nio-8080-exec-1] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
    filePath = C:\readfile\1.txt
    2017-01-13 20:35:21.296 ERROR 5092 --- [nio-8080-exec-1] o.s.batch.core.step.AbstractStep         : Encountered an error executing step step1 in job job
    
    java.nio.file.NoSuchFileException: C:\readfile\1.txt
        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) ~[na:1.8.0_101]
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) ~[na:1.8.0_101]
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) ~[na:1.8.0_101]
        at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230) ~[na:1.8.0_101]
    

    파일 생성: C:\readfile\1.txt, 그런 다음 다시 요청http://localhost:8080/launchjob, 결과 실패:
    
    2017-01-13 20:37:31.672  INFO 5092 --- [nio-8080-exec-3] c.j.s.controller.JobLauncherController   : JobInstance already exists and is not restartable
    2017-01-13 20:37:31.693 ERROR 5092 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
    
    java.lang.NullPointerException: null
        at com.loizenai.springbatch.controller.JobLauncherController.handle(JobLauncherController.java:33) ~[classes/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
    

    자세히 알아보기 - Spring Boot Batch 재시작 작업 예제



    관련 게시물:
  • SpringBoot and Spring Batch Integration
  • Spring Batch Decider Example
  • Angular 8 SpringBoot PostgreSQL CRUD Example
  • SpringBoot MongoDB Angular 11 CRUD Example
  • SpringBoot MongoDB Angular CRUD Example
  • SpringBoot Angular 11 Pagination Example

  • 참조 링크Configuring and Running a Job - Spring

    소스 코드 - Spring Boot Batch 재시작 작업 예제



    Spring-Boot-Batch-Restartable-Function

  • 좋은 웹페이지 즐겨찾기